skip to Main Content

I am trying to figure out how to structure my data regarding how users will be able to create friend relationships with each other. Per example, in my case I would want to have something like this: {uid1:accepted, uid2:accepted, uid3:declined, uid4:pending}.

So I want to have a list of friends and also the state which can be accepted, declined or pending.

I am just looking at firestore right now but maybe I should do this with realtime database? Anyways I will show you my problems when trying to figure out a solution with firestore.

My first idea:

Collection: users
    Document: uid1
         name: ‘something’
         friends: map with array of uid and state

Problem: let’s say the user uid1 was very popular and had millions of friends, that friends field map would surpresa the size limit of 1 MB per document imposed by firestore. So I was thinking how to solve this…

My second idea:

Instead of storing in a field I thought about creating a subcollection friends and then each document represent a uid and inside each document I would have a field indicating the state (accepted, declined, pending). This solution seems like very organized data wise however firestore charges per document read and storing 1 friend per document can’t be efficient cost wise for sure

Collection: users
Document: user123
Fields:
- name: "John Doe"
- email: "[email protected]"
- ...
Subcollection: friends
Document: friend456
Fields:
- state: "pending"
- timestamp: 1654390800 (example timestamp)

Conclusion:

1MB size limit per document doesn’t allow me to store friend list inside just 1 document and firestore charing per document read doesn’t allow me to create a subcollection friends and store each friend per document since it would be too costly.

Any experienced developer could give me some guidance? Thank you in advance

2

Answers


  1. The first approach is exactly as you described it.

    To take into consideration the second approach, that is to have a friends sub collection then you must think that getting one user friends will be easy, but if you need to, for example, querying over all users that have some conditions over friends, that case you will not be able to achieve it easily. This is because you need to query over all the users one by one and take the information regarding their friends(which is quite costly since you need to read much more data).

    If the issue in hand is retrieving all pending user of a particular user, I would go with the second approach. Keep in mind that if you have 500 friends per user then your app will be able to afford this type of queries. Also, you do not exactly may want to bring all of the 500 hundred users at single shot, instead you can use pagination which allows you to get only a certain amount of documents. Which can be really helpful in this case where you can have many friends.

    Lastly you may want to think which properties you need to show in the UI before setting up the fields for each document collections. for example if you need to show how many pending friends request a user has, you may want to include a pending_request field in the user document just to show that small piece of data. This way you avoid to retrieve all of the user and perform a count in the UI side(which is expensive).

    Login or Signup to reply.
  2. thanks for your reply.

    to provide more clarity, lets say users have a button called "my friends" and when they click a scrollable list pops up with list tiles with name, and image url from firebase storage. if users scroll down it seems a bit too costly to be charged 1 read in firestore per list tile rendered? i know i could then store locally but i was wondering how more experience people solve this types of problems. is creating:

    Collection: users
        Document: user123
            Fields:
            - name: "John Doe"
            - email: "[email protected]"
            - ...
            Subcollection: friends
                Document: friend456
                    Fields:
                    - state: "pending"
                    - timestamp: 1654390800 (example timestamp)
                    - name
                    - something else
    

    Do you think this is scalable? or you think i should use RealTime database, AWS or Hasura?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search