1
votes

I’m building a simple app in firebase where users can friend each other and upvote each other’s posts. However, you can only see upvotes made by mutual friends.

Ie: if bob likes joe’s post.

If I am friends with joe and bob, I can see bob’s like.

If I am only friends with joe, I cannot see bob’s like.

How should I structure my data? I’m planning to create PostFeeds for each user:

— PostFeed (collection)
     — Uid (document)
         — Posts (collection)
              — Likes (collection)

If I write a new post, it gets added to all my friends’ post feeds. If I have 1000 friends, that post will be added to 1000 feeds.

I am storing the likes for every post inside each Post in PostFeed . So we can get likes without an extra query. So if bob likes joes post, the like will be added to every Post in joe’s friends’ Post feeds.

Ie: if joe likes bob’s post and bob has 500 friends. Bob’s post is on 500 friends’ PostFeeds. Joe’s like should be added to all 500 Posts in each PostFeed.

But likes are only visible if we are mutual friends.

Ie: if bob likes joe’s post, it will only be added to a users feed if we are mutual friends. So look through joe’s posts where bob is a mutual friend and add the like to those posts.

Is this scalable? Although most the write takes place in firebase functions, It seems very expensive write operation. Especially if a user Likes, the Unlikes, then Likes again. Or if I add a new friend, I need to add all upvotes that new friend made on mutual friends’ posts.

Is there a better way to handle this?

1

1 Answers

0
votes

This is not a good approach.

For example, if two people become friends after they have written posts, then past posts will not appear in their feed. Also, if people unfriend each other, then all the postfeeds would need to be updated.

Instead, it should only store the actual information that took place, which is:

  • Vote ID (unique ID for this record)
  • Post ID (being voted upon)
  • User ID of person who liked the post

All of the "friend" stuff is then calculated on top of this record, either in real-time or occasionally recalculated and cached.

You might want to investigate usage of a graph database to store all of these relationships instead of a relational database.

See: TAO: The power of the graph | Facebook