Using multiple array-contains in firestore - firebase

In the following code, I want to use multiple array-contains queries, which is inappropriate according to firebase limitations.
await firestore
.collection("collection")
.where("field1", "array-contains", value1)
.where("field2", "array-contains", value2)
.where("field3", "array-contains", value3)
.get();
Tried to find a workaround solution by adding all values to one array and query on that array but it seems firebase does not support array-contains-all query.
Any suggestion how can I reframe my query?

Related

How to use whereIn filter multiple times in a query

I am using this code to retrive data from firestore
querysnap = FirebaseFirestore.instance
.collection("datas")
.where("cat", whereIn: Cateogryarray )
.where("City", whereIn:Cityarray)
.snapshots();
Then I get this error.
You cannot use 'whereIn' filters more than once.
How can I execute this query.
As the Firestore documentation on query limitations says:
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.
Since you're trying to use two in clauses in your query, Firestore gives an error.
The most common workaround is to run with one clause against the database (typically the one you expect to exclude most documents from the result), and perform the rest of the filtering in your application code.
Another idea is to get individual snapshots for each parameter that would need the inclause.
Then once you have each of your snapshots, do an intersection of the lists. This will return the results where every record adheres to each individual filter.

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 🙂

Sorting firestore collection before and after limiting

I am trying to get the last 1000 items from firestore and then sort them in ascending. So I tried
connection()
.collection(`somecollection`)
.orderBy("timestamp", "desc")
.limit(1000)
.orderBy("timestamp")
Having orderBy twice doesn't seem to work. But works with one orderBy
I know I could do this in client but is it possible to run this am I missing something here.
You don't even need to orderBy by ascending, as it is by default.
connection()
.collection(`somecollection`)
.limit(1000)
EDIT:
Firestore doesn't support the functionality you are looking for, so you need to query the initial data in a descending order, and the on client sort it in the way you need
connection()
.collection('somecollection')
.orderBy('timestamp', 'desc')
.limit(1000);

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