Firestore social media posts table

Viewed 754

so I want to create a sort of social media application and use firestore as main database.

the goal is to create "facebook" news feed.

each user will have a list of friends and each user will be able to create posts.

each post can be modified to be visible to all the users of the application or just the user friends. so each user will be able to post posts to all his friends and to post posts to everyone in the application.

also, users can "save" posts they liked in the newsfeed.(LikedPosts subcollection)

USERS (collection)
    DocumentID - userId gathered from Authentication uid
        firstName: String
        lastName:  String
        username:  String
        birthdate: Timestamp
        accountCreationDate: Timestamp
        FRIENDS (subcollection)
            DocumentID - userId of the friend
                username:  String
        LikedPosts (subcollection)
            authorUserId:   String
            authorUsername: String
            text:  String   
            imagePath: String

POSTS (collection)
    DocumentID - postId randomly generated
        authorUserId:   String
        authorUsername: String
        text:  String   
        imagePath: String
        likesCount: Number
        forFriendsOnly:yes
        LIKES (subcollection)
            DocumentID - userID of the liker
                username:  String

now in the newsfeed for a user - How can I query for all the visible post (forFriendsOnly:no) and also to all the posts for friend only, that the current user is in the author friends subcollection.

also, if the user change his name, how can I change his name accordingly for all his previous posts, and all the save posts related to the user?(located in user likedpost subcollection)

2 Answers

I guess you were asking 2 questions.

First, Firestore recommends data duplication instead of joining query across collections. The way you designed the post and user has to rely on query concept in SQL.

It is still possible to achieve that, if you don't mind to have all the author's friend id as an array inside of that post document. Meanwhile, you have to sync author's friend array through trigger function when author add/delete friends.

I wouldn't really recommend this solution, because as a social platform, user's friends might be changing constantly, then you have to keep on updating all his post's friend array.

There is another solution, which is add one more subcollection under user as his visible "feeds". Then whenever an author creates a post, trigger function will write this post's summary to all his friends' visible "feeds" collection.

However, both above solutions are not perfect if you are concerned about accuracy, realtime, cost, etc. I guess that is the drawback we have to bear with. If you have to achieve the same thing as SQL, I guess the only option is using other solutions for query part, such as elastic search, mysql, neo4j, etc. PS: You can still wrap it with cloud functions.

Regards to your 2nd question, one way is not duplicate username if you think your user would change their name frequently. And always query username by user id from user collection. The other way is using trigger function to update the duplicated username when user change their names. I would recommend the second way, since user wouldn't change their names frequently.

Not necessarily related to your original question, but your LikedPosts subcollection likely needs a restructuring. If you can ensure uniqueness on your postId, then it should probably be something like:

LikedPosts (subcollection)
  postId: Unique identifier for liked post
    authorUserId: String
    authorUsername: String
    text: String
    imagePath: String

The current structure only allows for one liked post, so you'll need to change it to be one document per liked post, or a document containing a list of all of the liked post ids.

Related