2

I am currently creating a sort of social media app and like any social media app, it is almost crucial to display some sort of information from friends.

I have tried various ways to display posts to users that their friends have posted but it can be slow and I doubt it is the most efficient way.

At first I had structured my database as following:

users -> (uid) -> friends(array of uid's) posts(array of post id's) other info...

posts -> (post id) -> image_url other info...

With this setup I: 1. I took the current logged in users uid and got the document that belongs to that user under "users".

  1. I then got that users friends list as an array and looped through them.

  2. For each uid I then queried the "users" once more and found the document that belongs to that user.

  3. I then took the first "post id" in their "posts" array if there was one

  4. I took the post id and found the corresponding post in the "posts" collection and downloaded it.

  5. Repeat step 3 - 5 for every user id until there are no more posts, or i have downloaded 10 of them.

That was my first approach, however there are several problems with this that I can identify and most likely several more that I havent thought of yet.

  1. In steps 2 and 4. In these two steps I am downloading a whole array due to the fact that firestore will not allow you to download a certain index in an array. This slows down the process, image if there where

  2. Lets say the user scrolls down to refresh new posts then it would be difficult to load more posts because even if i start downloading where i left of, another post could be added in that time which throws the whole system of.

I am also experimenting with just having a collection call posts with post documents in them attatched to each user.

Any other ideas?

1 Answers1

0

If I'm understanding your problem correctly, you are trying to facilitate a joins between a user and posts (i.e. you want all posts that user can see ordered by time or relevance). I would suggest creating a Firebase Function that writes a record under a users 'feed' collection when one of their friends creates a post. The record will contain a Reference to the post and the necessary info to rank/order the post. Then you can just make two queries (the first being relatively fast and pageable) to facilitate a feed for the user. If a user acquires a new friend, then just have another Firebase Function to pull in somewhat recent (probably not from the beginning of time) posts from that friend.

Bryan Massoth
  • 1,109
  • 6
  • 7
  • the only issue with this is it could take several requests on the functions server, image someone has 100 followers, you would need to query for each friend and then put in a reference – Zachary Gameiro May 02 '18 at 01:23
  • Like I said, you are trying to perform a `joins` (something that isn't possible using Firestore); so either way you do it, it will not scale well. So you have to answer the following questions, do I want the user to see the expensive part, and do I want to be proactive about the work needing to be done. With your current solution, you have to repeat the expensive part every read. With this solution, you do it once and the user doesn't see any of the expensive execution. – Bryan Massoth May 02 '18 at 16:57
  • Alright thank you for your suggestion, I will give it a try – Zachary Gameiro May 03 '18 at 15:35
  • sorry i just noticed one problem with this solution. Not that I am trying to sound cocky or anything and I understand that my app will most likely never see the day where it reaches millions of users. However in the unlikely chance it does, if there where a person with lets say 1 million 'followers', wouldn't writing to a user feed be inefficient for 1 post, it would mean that you would have to do this one million times. – Zachary Gameiro May 10 '18 at 00:51
  • Yes it is costly, but anyway you try to allow this is costly. Here is an article about how Facebook and Twitter use fan out read vs write: [link](https://www.quora.com/What-is-fan-out-write-and-fan-out-read-in-scalability). Hope it helps. – Bryan Massoth May 11 '18 at 16:01
  • Thank you very much – Zachary Gameiro May 11 '18 at 17:11