This question already has an answer here:
Between StartDate and EndDate Firestore
(1 answer)
Closed 3 years ago.
I have a collection of events in my Firestore database where each one has a startDate and an endDate. On client side I would like to query for events that are happening right now. Normally, you would just check if currentDate is inside the time interval, however this can't be done with Firestore since it is disallowed to have more than one comparison query.
Has anyone encountered this problem and how did you overcome it?
I you are storing the startDate and endDate as milliseconds, you could just take your client time in milliseconds and make a query against your events to know if it has already started, is ongoing or is done.
Personally I usually store dates in millis to make queries and also in a human readable format when I check the documents using the Console.
however this can't be done with Firestore since it is disallowed to have more than one comparison query
No, you can query a Firestore collection using multiple comparison functions but only on the same property and not on multiple properties as you intend to do. According to the official documentation regarding query limitations:
Query limitations
Cloud Firestore does not support the following types of queries:
Queries with range filters on different fields, as described in the previous section.
So as you have probably noticed, Cloud Firestore allows a range filter on a single field. The most reasonable explanation is that Firestore cannot guarantee its performance in such a case.
To solve this, you'll have to query your collection twice and combine the results of those queries on the client. It's not perfect since you need to query twice, but I think it will do the trick.
Related
I was watching this Firebase video, and one stuff that wasn't clear to me is that the "||" or OR operator isn't supported especially with the way Firebase store indexes.
It was stated that you have to make separate queries and join it on the client side instead of on the firebase side.
Isn't the in operator essentially just a convenience method and acts like multiple OR statements?
https://firebase.blog/posts/2019/11/cloud-firestore-now-supports-in-queries
It is a well known feature of Firestore indexes which are good for range queries. With the indexes applied , for an inequality query, the backend would still have to scan every document in the collection in order to come up with results, and thus will affect the performance when the number of documents increases with time.
So, as per your question regarding the backend logical working of the “in” operator when used in a query and which is also mentioned in this thread on addition of IN queries not only address this performance issue but also supports up to 10 equality clauses on the same field with a logical OR".The arguments which are passed in the “In” operator query, are compared when searching a document.This will allow you to fetch documents with your filter criteria and thus result in function operation to take less time rather than goind one by one through each item.
For the example you could do:
// Get all documents in 'foo' where status is open or upcoming
db.collection('foo').where('status','in',['open','upcoming']).get()
I would also recommend you to check these following similar examples:
How to perform compound queries with logical OR
How to make queries on firestore
Firebase database operator working
Firestore IN operator working
Firestore Query limitation
I am wondering how to filter firebase firestore by date field, as I can't see data type other than String, Number, Boolean
As below, please advice if someone find a way to filter firestore collection based on date field.
I think it's not possible at the moment. I found this documentation on GCP which is practically the same UI. There is a little bit about filtering, but not many details.
I think that this UI is just for support/test purposes not for everyday use so such feature is not really needed. It's working with API with no problem ( you can check example in JS in this SO question).
If you need this feature you should raise a Feature Request here.
I believe the only thing you can do at this point is apply a filter on your timestamp fields and set the sort order without a condition. The results will show the timestamp field value so it is easy to scan for the time range you are interested in.
Obviously this is not awesome for large document sets where the interesting date is somewhere in the middle but at least sort order will let choose if you want to scroll from the first or last documents by date.
This approach is described in a Firebase Blog post:
Sort and Filter in the Firestore Console
I have documents with a startDate and endDate. I would like to query between the range of the startDate and endDate. I can query between a range for one date like so:
whereField("startDate", isGreaterThan: start).whereField("startDate, isLessThan: end)
But I cannot query two fields like so:
whereField("startDate", isGreaterThan: start).whereField("endDate", isLessThan: end)
Firestore throughs an exception when using more than one field in a compound where statement.
No matter what is the platform that you are using for building your application, I'm sure that the error that you get is quite explicit. Cloud Firestore official documentation is also quite explicit regarding this topic. So there are some query limitations, when it comes to Firestore:
Cloud Firestore does not support the following types of queries:
Logical OR queries. In this case, you should create a separate query for each OR condition and merge the query results in your app.
So a Firestore query can perform a range filtering only on a single property. Since you are trying to filter ranges on two properties, you're geeting that error message and this is the expected behaviour since this is not possible in a single Firestore query.
To solve this, you can choose from one of the following solutions:
You can perform filtering on one (first) field in the query and on the other (second) field client-side, as also the official documentation indicates.
You can combine the values of the two range into a single field in some way that allows your use-case with a single field. A very successful example of such a combination would be the use of geohashes for filtering on latitude and longitude properties as Frank van Puffelen explained very well in this video, Querying Firebase and Firestore.
Another option is to change the way your are storing your data and model it differently. The most simple implementation would be to put all items within the startDate and endDate into a single collection. Since you didn't choose a tag for a platform, I will write the necessary query in Javascript but it can be simply written also for other programming languages. So you can query that collection with the following query:
db.collection("startDate-endDate").where('date','>=', start).where('date','<=', end);
Another even more general alternative would be to store all your items in a collection for each periode you need (year, monts or days) separately, and then perform the necessary number of queries to get the items you are looking for one of each collection, itemsFromFirstYear, itemsFromSecondYear and so on.
Please take also take a look at the official documentation regarding:
document on compound queries and their limitations
video on Cloud Firestore queries.
IMHO, I'd recommend picking up the first option.
I have documents with a startDate and endDate. I would like to query between the range of the startDate and endDate. I can query between a range for one date like so:
whereField("startDate", isGreaterThan: start).whereField("startDate, isLessThan: end)
But I cannot query two fields like so:
whereField("startDate", isGreaterThan: start).whereField("endDate", isLessThan: end)
Firestore throughs an exception when using more than one field in a compound where statement.
No matter what is the platform that you are using for building your application, I'm sure that the error that you get is quite explicit. Cloud Firestore official documentation is also quite explicit regarding this topic. So there are some query limitations, when it comes to Firestore:
Cloud Firestore does not support the following types of queries:
Logical OR queries. In this case, you should create a separate query for each OR condition and merge the query results in your app.
So a Firestore query can perform a range filtering only on a single property. Since you are trying to filter ranges on two properties, you're geeting that error message and this is the expected behaviour since this is not possible in a single Firestore query.
To solve this, you can choose from one of the following solutions:
You can perform filtering on one (first) field in the query and on the other (second) field client-side, as also the official documentation indicates.
You can combine the values of the two range into a single field in some way that allows your use-case with a single field. A very successful example of such a combination would be the use of geohashes for filtering on latitude and longitude properties as Frank van Puffelen explained very well in this video, Querying Firebase and Firestore.
Another option is to change the way your are storing your data and model it differently. The most simple implementation would be to put all items within the startDate and endDate into a single collection. Since you didn't choose a tag for a platform, I will write the necessary query in Javascript but it can be simply written also for other programming languages. So you can query that collection with the following query:
db.collection("startDate-endDate").where('date','>=', start).where('date','<=', end);
Another even more general alternative would be to store all your items in a collection for each periode you need (year, monts or days) separately, and then perform the necessary number of queries to get the items you are looking for one of each collection, itemsFromFirstYear, itemsFromSecondYear and so on.
Please take also take a look at the official documentation regarding:
document on compound queries and their limitations
video on Cloud Firestore queries.
IMHO, I'd recommend picking up the first option.
This question already has answers here:
Firestore multiple range query
(3 answers)
Closed 4 years ago.
We are building a app where we need to show nearby posts, made by users. A post should only be shown, if it is not more as 4 hours since posting. Because firestore doesn't provide geoquerys, i have to do a search, where all posts in a specific square are returned. This is my current query:
collection("posts")
.where("creation", isGreaterThan: DateTime.now().subtract(Duration(hours: 4)))
.where("location", isLessThan: cornor1OfSquare)
.where("location", isGreaterThan: cornor2OfSquare)
The problem with this query is, that it's not allowed to add multiple where statements filtering on different fields.
Filtering by one property locally and one on the server side is not possbile, because we have millions of posts in our app.
Is there any other way to do this? For example restructure the data on the server, to make queries like this possible? I researched, but only found solutions, with "simple" data. But i have a Timestamp and a GeoPoint field, which makes it more complex.
The second approach, which comes to my mind, is to use cloud functions, but i have no idea how to do that, and if it is the best solution available.
I am programming in Dart/Flutter.
The Cloud Firestore doesn't support range filters on different fields.
You most create separate query for each OR condition and merge the query results.
See this link for more: https://firebase.google.com/docs/firestore/query-data/queries?hl=en-us