Reputation: 4137
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:
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
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