I want to learn firestore and to this end I created small project which replicates instagram. Not all functionalities of course, just the very basics - photo sharing, comments and the possibility to report a comment or a photo.

This is how my current collections look like:

users -> user_id -> [username, email]
following -> user_id -> usersFollowing -> [list of user ids]

//my most difficult collection

posts -> user_id -> userPosts -> post_id (this is the photo id) -> [caption, creationDate, url [likes], [comments]] //likes and comments are subcollections where I respectively store ids of people who liked the photo and in comments I store the id of the people who commented and the actual comment

Here is my question. I want to be able to report photo or a comment (as abusive, inappropriate, etc). I thought of creating collection reports where I will have two subcollections photos and comments; Each one of this subcollection will have a doc photoId or commentId and each doc will contain the following info: reportedBy <- the user_id of the person who reported the photo/comment; date <-the date it was reported

So far so good. However, if a photo/comment have lots of reports eventually I may want to delete it. How do I do that? I have only the photo/comment id stored in my Reports collection. I guess this is a sign that my collection is not properly structured? Maybe alongside reportedBy and date fields I should store several more fields: like userId <- the id of the user which created that post (photo or a comment) and postId <- the id of the post to which that particular comment belongs. Is that a good approach or not really? Are there any better suggestions?


The structure of your data highly depends on what cases you want to optimize for. If you look for read performance you might want to denormalize the data you store. That means you might have duplicated information but it will be easier and cheaper to retrieve it than perform multiple get calls. This has a drawback, it will be harder to update and write data as it is now duplicated. In a blog, this would be mostly the case in my opinion as you expect that people will read posts more often than they write them. This part is more of an fyi, don't be afraid of duplicate information.

Now, "posts -> user_id -> userPosts -> post_id" this nesting might be good or bad depending on how you want to display the posts on the website. If you have to reach someone's profile to view their posts it's okay. But, if you want to have feed of posts that is searchable you might want to have something like this "posts -> (user_id, post_id, post_data) so you don't have to query across each user's collections. This might also be easier to integrate with Algolia for example.

"However, if a photo/comment have lots of reports eventually I may want to delete it. How do I do that?" - Well you need cloud functions to watch the collections for changes. Whenever a new report is added to the collection, you want to update the count of reports and check if it's over your limit then take an action. For performance reasons you do not want to count all occurrences of the postId in the reports collection each time. This means that you either add a reports count on the actual post in the posts collection or structure the reports like "reports -> (post_id, report_count) -> (user_id, date).

You can find here a playlist explaining a few recommended practices for working with the firestore. Later on in the same playlist, you can find this video explaining how to watch for events that happen on collections.

If you have more questions or something is not clear enough, reply and I will update my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.