Home > Net >  How to have realtime many to many two way references in firestore
How to have realtime many to many two way references in firestore

Time:12-22

I have a user collection in firestore and each user object has an array of references to "tasks" that they have applied to. Tasks is a separate collection as well and each task object has a user ref array as well.

Collection Tasks: 
doc: {
   name: "Do something",
   time: "Time",
   users: ["/users/u1", "/users/u2"]
}

Collection Users: 
doc: {
    name: Username,
    tasks: [ "/tasks/docRef", "/tasks/anotherDoc" ]
}

I have a screen in my react-native app that lists all the tasks and when a task is clicked, it goes to a details screen that displays all the users in a list as well.

Is this the best approach to have this kind of data? Or should I have collections instead of arrays with references. I refrained from collections to prevent duplication of data but I'm not sure if they will be more efficient.

CodePudding user response:

(From the comments )I wanted to inquire if this was the right approach to store the data?

1/ Should I just use uids and then query the collection to matching those ids?

Storing uid or DocumentReferences in the arrays will not make a difference in terms of ease of querying the corresponding documents. It would only make a difference at the level of the size of the document containing this data since DocumentReference`s are longer than uids).

2/ Or create a sub-collection in the user document itself with references to the tasks?

In the NoSQL world you should not hesitate to denormalize your data.

So having the tasks list in a user doc AND having the users list in a task doc and synchronize the docs when a change is done in one of the collections is a valid approach.

HOWEVER, you may encounter a problem if you have "a lot" of tasks for a given user or a lot of users involved in a task since you may hit the maximum size for a document which is 1 MiB (I agree that you need a LOT of tasks or users :-)).

To avoid that I would advise using sub-collections. This is also the preferred approach if you plan a high frequency of changes that could cause database contention or higher latency, see the documentation section about "Designing for scale".


If the user data you want to show in a task is limited (e.g. just their name plus a button to open each user Profile based on the uid) I would keep an array of users in the task document with this limited amount of data (of course after being sure that there is no risk that a doc reaches the limit of 1 MiB). And have a sub-collection of task documents under each user doc (as advised above).

CodePudding user response:

Modeling well in firestore is a bit difficult, you have to think hard about your use case.

Don't worry about data duplication, this is very common in Firestore. Remembering that you mainly pay for the number of reads and writes.

In your user array, you could keep the necessary data to save you from doing more reads on the user collection.

In your example, the user only has the username, you could keep the username and uid, saved in tasks. That way, no reads would be done on the user collection.

What if the user changes username? Use a batched writes and update all docs that contain that user.

  • Related