b-fg
b-fg

Reputation: 4137

What to do when custom index is not an option in Firestore

In my Cloud Firestore database I have a collection of users and a collection of events. A user can attend to multiple events by requesting them to the owner, so in every event I keep track of this as shown below:

enter image description here A query to get all the events a user is participating in is:

String participating = "participants_id." + myUserID;
query = FirebaseFirestore.getInstance().collection("events").whereEqualTo(participating, true);

The problem is that if I want to paginate these results I need to order and limit the query and this requires a custom index. So this index would be required for each "participants_id." + myUserID field, which is not scalable (max custom index are 200).

So how can I solve this? I could denormalize the events collection and add a participating subcollection for each user copying the event document there as well. But I would prefer to avoid denormalizing if possible since it becomes a bit messy. Is there any better option?

Upvotes: 1

Views: 544

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 138989

Cloud Firestore automatically creates indexes on individual fields of your documents. Complex indexes that span multiple fields can only be created manually in the Firebase Console. Unfortunately, you cannot programmatically create indexes, at least for the moment.

In your scenario, you should definitely use denormalization. One reason for using denormalization is because there is also a limit regarding the maximum size for a document, which is 1Mib. So if you have too many participants, you can reach this limit very quickly. See here Firestore quotas and limits.

So, you typically should consider augmenting your data structure to allow a reverse lookup. For example, I'd add a participating subcollection where you keep the lists for each user or you can add it as a top level collection and your database structure should look like this:

Firestore-root
   |
   --- users (collection)
   |      |
   |      --- userId (document)
   |           |
   |           --- //user details
   |
   --- userEvents (collection)
   |     |
   |     --- userId (document)
   |           |
   |           --- events (collection)
   |                 |
   |                 --- eventId
   |                       |
   |                       --- //event details
   |
   --- events (collection)
         |
         --- eventId (document)
               |
               --- //event details

Using this database structure, you can query your database very quickly to get all the events that correspond to a specific user. And as far as I know these are the only options that you have.

Upvotes: 1

Related Questions