Consider I have an Events collection where it has startTimestamp and endTimestamp indicating when the event starts, ends respectively.
How to query in firestore to find out if the Event is live/finished/upcoming?
Consider I have an Events collection where it has startTimestamp and endTimestamp indicating when the event starts, ends respectively.
How to query in firestore to find out if the Event is live/finished/upcoming?
If both startTimestamp
and endTimestamp
properties exist in the database and are of type Date
and not String or Number, then you can simply use a query to check if a particular date is within the bounds or not.
For example in Android, if you want to check if a particular date is within the bounds, you might think that a query like the one below will work:
eventsRef.whereGreaterThanOrEqualTo("startTimestamp", yourDate)
.whereLessThanOrEqualTo("endTimestamp", yourDate);
But it won't. You'll get an Exception with the following message:
All where filters other than whereEqualTo() must be on the same field. But you have filters on 'startTimestamp' and 'endTimestamp'
The only solutuin you have is to create three separate queries.
Edit:
According to your comment, one query should check if your yourDate
is before startTimestamp
eventsRef.whereLessThanOrEqualTo("startTimestamp", yourDate);
If it is, it means it's an upcoming event.
The second one would be to see if it's grater than the startTimestamp
:
eventsRef.whereGreaterThanOrEqualTo("startTimestamp", yourDate);
Where we have two cases. One case, you perform a new (third) query to check if the data is less than endTimestamp
:
eventsRef.whereLessThanOrEqualTo("endTimestamp", yourDate);
If it is, it means that the event is within the bounds, so it's a live event otherwise is grater than that which means that the event is finished.
To get that data in realtime, you should use a snapshot listener for every query.
Here are the cases to handle this scenario. I'm pretty sure this is a very common problem but didn't find effective solutions for this anywhere.
Solution 1: Have all documents in a single collection called subscribedEvents As suggested Alex, We need to do for the following status.
Upcoming : currentTimestamp < startTimestamp
Finished : currentTimestamp > endTimestamp
Live : currentTimestamp > startTimestamp in 1st Query and currentTimestamp < endTimestamp in second query.
Problem : I can have lots of documents (nearly 10,000) in subscribedTimestamp and Live condition is not scalable as I can't limit the results while querying. As it needs to be intersected from the two queries, I need to query with out filters.
Solution 2: This is a bit of hack but scalable. Don't have all the documents in a single subCollection. Separate Upcoming events and put those documents in subscribedEvents/others/Upcoming collection.
When a user subscribes, If its an upcoming event, you can directly store in the subscribedEvents/others/Upcoming collection.
Rest of the documents can go directly into subscribedEvents collection.
Upcoming : Query all the documents with a limit filter from subscribedEvents/others/Upcoming collection.
Finished : currentTimestamp > endTimestamp
Live : currentTimestamp < endTimestamp
The benefit with this structure is we can apply limit filter and lots of documents don't need to be read for your query and there will be only one query required for each status.
Now this step needs additionally a cron job to make sure the upcoming events from the upcoming sub-collection are moved back to subscribedEvents.
However, if you have lesser documents, Solution 1 is the way to go. But not in my case.
Hope it helps someone where they have to scale efficiently.