Where, Firestore queries on Flutter, doesnot have "notEqualTo" condition [duplicate] - firebase

This question already has answers here:
Firestore: how to perform a query with inequality / not equals
(7 answers)
Closed 3 years ago.
I am fetching a data from fire-store I have an order Object which have a status as an attribute that can be "pending"," delivering","delivered".
What I want to do is getting all the orders except the one with status "delivered"*.
How I can do that with Where clause ?
return _fs
.collection('orders')
// .where('status', ' ', 'delivered')
.where('deliveryTime', isGreaterThan: startTime)
.where('deliveryTime', isLessThan: endTime)
.snapshots();
any help will be appreciated

You can view the "Query limitations" section in the querying article:
Cloud Firestore does not support the following types of queries:
Queries with a != clause. In this case, you should split the query into a greater-than query and a less-than query. For example, although the query clause where("age", "!=", "30") is not supported, you can get the same result set by combining two queries, one with the clause where("age", "<", "30") and one with the clause where("age", ">", 30).
return _fs
.collection('orders')
.where('status', isGreaterThan: 'delivered')
.where('status', isLessThan: 'delivered')
.snapshots();
However
As you can see, I removed the range filter on deliveryTime because it is impossible to perform range filters on multiple fields as explained here:
You can only perform range comparisons (<, <=, >, >=) on a single field, and you can include at most one array-contains clause in a compound query[.]

Related

How To Use arrayContains and not-in filters in a Firestore query?

When I run arrayContains and whereNotIn together in a Firestore query like the code below:
firebaseFirestore.instance
.collection('users')
.where('onlineStatus', isEqualTo: true)
.where('location', isEqualTo: userFrom.location)
.where('interest', arrayContains: callInterest)
.where('userId', whereNotIn: ['a','b','x']).limit(1).get();
My app crashed with the following message
An error occurred while parsing query arguments, this is most likely
an error with this SDK......
Taking away the whereNotIn clause removes the error, so the error is most likely caused by using arraycontain and notIn together.
The documentation on firestore merely states that not-in should not be used in the same query as array-contains-any. So I'd assume that not-in can work with array-contains but it seems to be otherwise.
Does anyone know if arrayContain can be used with notIn in a query together? Any advice would be appreciated. Thanks.

Flutter Firestore: An error occurred while parsing query arguments on using whereNotIn and arrayContains at the same query

My query is:
snapshot = await FirebaseFirestore.instance
.collection('dialogs')
.where('active', isEqualTo: true)
.where('users', arrayContains: globals.user.userId)
.where('readers', whereNotIn: [globals.user.userId])
.orderBy('priority')
.limit(1)
.get();
I'm getting the above exception:
Unhandled Exception: [cloud_firestore/unknown] An error occurred while parsing query arguments, see native logs for more information.
I have found some notes on the official Firestore documentation:
You can use at most one in, not-in, or array-contains-any clause per query. You can't combine these operators in the same query.
You can't combine not-in with not equals !=.
All should be just fine in my case.
Also I have tried several things:
If I remove only the whereNotIn line, everything is just fine.
if I remove only the arrayContains line, everything is just fine.
Why am I getting a query parsing exception?
Thanks
TL;DR
Firestore query documentation was not up to date (relevant for 04.04.21).
More details
I have checked my android Logchats on android studio and found out that:
Invalid Query. You cannot use 'not_in' filters with 'array_contains' filters.
While firebase documentation says that:
You can use at most one in, not-in, or array-contains-any clause per query. You can't combine these operators in the same query.
It was not mentioned on the Firebase documentation that array-contains cannot be at the same query along with not-in.
Conclusion
If you are encountered with query parsing exception. The most updated and fastest way to get relevant information about the problem is to check your Logchats.
Firestore Limitation
Firebase firestore doesn't allow you to use whereNotIn and arrayContains in a single query. see here
SOLUTION
Split the query, first get entires by
snapshot = await FirebaseFirestore.instance
.collection('dialogs')
.where('active', isEqualTo: true)
.where('users', arrayContains: globals.user.userId)
//.where('readers', whereNotIn: [globals.user.userId]) <-- remove this
.orderBy('priority')
.limit(1)
.get();
Then filter the received snapshot locally ( say in a for loop )
Though it will work but bear in mind that this will be a performance hit. So, the best approach is to avoid such queries.
Hope this helps 🙂

Flutter firebase get documents where today is in between to fields - date range (startDate / endDate) [duplicate]

This question already has an answer here:
Between StartDate and EndDate Firestore
(1 answer)
Closed 2 years ago.
I have some documents in my firestore with "startDate" and "endDate".
Now I want to get every document where today's day is between startDate and endDate.
final DateTime dateTime = new DateTime.now();
final QuerySnapshot querySnapshot = await colRef
.doc(docId)
.collection('subCol')
.where('startDate', isLessThanOrEqualTo: dateTime)
.where('endDate', isGreaterThanOrEqualTo: dateTime)
.get();
The error is very self-explanatory:
I/flutter ( 5978): 'package:cloud_firestore/src/query.dart': Failed
assertion: line 490 pos 18: 'hasInequality == field': All where
filters with an inequality (<, <=, >, or >=) must be on the same
field. But you have inequality filters on 'FieldPath([startDate])' and
'FieldPath([endDate])'.
But there must be a solution for my problem without filtering clientside. Is it perhaps possible to create an index for this and if so, what does it look like? Other approach would be to save anyhow the date range in one field instead of startDate/endDate, but but here I would know even less how to filter it. Such a simple problem in SQL, so hard in Firebase....
Kind regards,
Jakob
Yeah, "there must be", but there isn't. You'll have to be a bit more practical. I have a similar situation, but in my case, I know (my code, my rules) that events are less than a week long. To reduce the number of documents read in the query, I filter on
.where('startDate', isLessThanOrEqualTo: dateTimePlusMaximumEventInterval)
.where('startDate', isGreaterThanOrEqualTo: dateTimeMinusMaximumEvntInterval)
(i.e. less than the maximum Event Interval in the future, and no more than the maximum event length in the past )
...and then do the rest locally.
This has to do with how Firestore uses the indexes to rapidly split results, and shard the data in a way that scales.

Firestore compound query with <= & >=

I need to query a firestore collection for entries where a start time (which is a number) is >= slot.start and and <= slot.end.
like this:
.collection('Entries', ref => ref
.where('timeStart', '>=', slot.timeStart)
.where('timeEnd', '<=', slot.timeEnd))
but I get this error:
Invalid query. All where filters with an inequality (<, <=, >, or >=) must be on the same field.
I thought this query would work with composite index but as the error says that does not work.
When I change the query to this:
.collection('Entries', ref => ref
.where('timeStart', '==', slot.timeStart)
.where('timeEnd', '<=', slot.timeEnd))
I can create an index for it. Furthermore when I change the 2nd '<=' to an '==' aswell I don't even need an index for it.
I didn't think my query is that advanced and I'm a little bit disappointed that firestore can't do this query. So what is the best solution for my problem? Is the next best thing to omit the 2nd query statement like this
.collection('Entries', ref => ref.where('timeStart', '>=', slot.timeStart))
And then iterate through the results and check if timeEnd <= entry.timeEnd "manually"? That seems like a really bad solution for me because I may need to load a lot of data then.
You're going to have to pick one field and query that one then filter out the other on the client side. Compound Queries documentation is firm on this one.
You can only perform range comparisons (<, <=, >, >=) on a single field, and you can include at most one array_contains clause in a
compound query:

How to use not/ inequality operator in cloud firestore?

I have list of strings, and using not operator I wanted to select all values except one. But I couldn't find anything about not opertor in the firebase website. Please help me with this issue.
P.S: This Link explains how to do the inequality operation with numbers, and not strings
It's a limitation with Cloud Firestore queries. But I found a workaround.
Cloud Firestore Documentation states,
"Queries with a != clause. In this case, you should split the query into a greater-than query and a less-than query. For example, although the query clause where("age", "!=", "30") is not supported, you can get the same result set by combining two queries, one with the clause where("age", "<", "30") and one with the clause where("age", ">", 30)."
New update on Firestore now supports not equal and not in queries. As mentioned here:
const capitalNotFalseRes = await citiesRef.where('capital', '!=', false).get();
const notUsaOrJapan = await citiesRef.where('country', 'not-in', ['USA', 'Japan']).get();

Resources