Firebase check if item is not in array in Flutter - firebase

I want to check in my Flutter app if an item is not in an array. If it is in it I want to sort it out, if not I want to take it.
There is an arrayContains function for the reverse function, but I couldn't find an arrayContainsNot function or something. How can I solve this?
I want to do it like this:
await FirebaseFirestore.instance
.collection("someCollection")
.where("someArray", arrayContainsNot: "someItem")
.get();

You can use the not-in operator.
A not-in query returns documents where the given field exists, is not
null, and does not match any of the comparison values.
So your code becomes:
await FirebaseFirestore.instance
.collection("someCollection")
.where("someArray", whereNotIn: ["someItem"])
.get();
Note that it supports up to 10 comparison values which have to be passed in a list to the whereNotIn property.

Related

how we can run multiple queries on Firebase/firestore to get filtered data in flutter?

how we can run multiple queries on Firebase/ firestore to get filtered data in flutter or any other possible solution? there is a picture storing dummy data in goal and title and wanna users according to the goals and titles filters.
Where() is a function provided by Firebase to query data
FirebaseFirestore.instance.collection('yourCollectionName').where('field1', isEqual:'value1').where('field2', isEqual: 'value2').get();
you can read more about it in the querying section at https://firebase.flutter.dev/docs/firestore/usage/
By looking at your Firestore database it is clear that you want to filter the documents based on two array fields goals and titles.
Firestore supports the arrayContains filter in the where clause by which you can filter data from an array inside Firestore. So you may think of doing something like this -
var filter1 = 'Hire Employees';
var filter2 = 'CEO';
FirebaseFirestore.instance
.collection('collectionId')
.where('goals', arrayContains: filter1)
.where('titles', arrayContains: filter2)
.get()
.then((QuerySnapshot docs) => {
for (var element in docs.docs) {print(element.data())}
});
But the above will throw an error saying that You cannot use 'array-contains' filters more than once. This is because Firestore has a limitation that you can use at most one array-contains clause per query which is documented here. So it is not possible to do something like the above.
I am not very sure of your use case, but as a workaround, you can restructure the database structure by making any one of the array field to a map, something like the following -
By making the structure like the above you can use multiple where clauses with one arrayContains filter and one isEqualTo filter which will look something like this -
var filter1 = 'Hire Employees';
var filter2 = 'CEO';
FirebaseFirestore.instance
.collection('collectionId')
.where('goals.$filter1', isEqualTo: true)
.where('titles', arrayContains: filter2)
.get()
.then((QuerySnapshot docs) => {
for (var element in docs.docs) {print(element.data())}
});
As the idea of allowing multiple arrayContains filters is currently not supported, but could be valid, I would recommend you file a feature request.

how to query (filter) documents from firebase to flutter app based on a value nested in a List of Maps?

im trying to get documents from my 'Patients' Collection which contain an array of maps 'Appointments' based on the value of 'translator' key as shown here:
here is how im trying to query the documents but i guess im having a syntax error
static Stream<QuerySnapshot> getSpecificUserAppointments(String translatorName) {
return FirebaseFirestore.instance
.collection('Patients')
.where('appointments', arrayContains: translatorName)
.snapshots();
}
i also tried to filter this way
.where('appointments.translator', arrayContains: translatorName),
.where('appointments.translator', isEqualto: translatorName)
still not getting results
any help would be appreciated
The arrayContains operator checks whether the exact, complete item you specify exists in the array. So your check would only work if the appointments array contained an entry that has a single string as its value with translatorName.
If you want to check whether a certain name exists, add an additional array field to your document with translatorNames, where you keep just the (unique) names of the translators in the document. Then you can use that field to query:
return FirebaseFirestore.instance
.collection('Patients')
.where('translatorNames', arrayContains: translatorName)
.snapshots();

using two queries to get 'data1' OR 'data2' in flutter firebase

I want to get data from firebase only if the user is not saved in the document. Because I need a or-query, which is not possible in Firebase, I decided to use RxDart's CombinedStreams with two steams:
var streamOne = FirebaseFirestore.instance
.collection('jobs')
.where('jobState', isEqualTo: 1)
.where('userOne', isNotEqualTo: FirebaseAuth.instance.currentUser!.uid)
.snapshots();
var streamTwo = FirebaseFirestore.instance
.collection('jobs')
.where('jobState', isEqualTo: 1)
.where('userTwo', isNotEqualTo: FirebaseAuth.instance.currentUser!.uid)
.snapshots();
But my app shows the data even if the current user is in 'userOne' OR 'userTwo'. Is it possible to avoid this and get the data just if the currentUser is not 'userOne' OR 'userTwo'?
Your logic is flawed: if the UID is in userOne, the second query will still return that document, and vice versa. What you want is actually an AND: the documents where the UID is not in userOne and not in userTwo.
Unfortunately though that query also isn't possible on Firestore, as all not-equal conditions in a query must be on the same field.
There is no way to capture your logic in a single query, and you will have to filter the documents fo userOne and userTwo in your application code instead.

Cloud Firestore OR query

How do I fetch multiple documents from firebase? I want to fetch all of the documents that are in a list.
I can only run the below query if instead of a list I pass it a single item for the owner field since isMemberOf is not a real operator. I put it there as something that I imagine it might look like.
Right now I can only pass a single value and use isEqualTo: instead of my made up operator.
How do I do this?
Stream<List<Event>> subscribeToEventsByDates(
List<String> users, DateTime start, DateTime end) {
return Firestore.instance
.collection('events')
----> SELECT * (all that match) <------- doesn't exist? How to do this?
.where('owner', isMemberOf: users)
.where('start', isGreaterThanOrEqualTo: start)
.where('start', isLessThanOrEqualTo: end)
.snapshots()
.map((snapshot) => snapshot.documents
.map((event) => Event.fromJson(event.data))
.toList());
}
If you want to pass an array of strings to a filter to match any one of them for a given field, that's called an "in" query.
The API documentation for where() suggsets that you should use "whereIn" for that.
.where('owner', whereIn: users)
From the documentation on in queries:
Use the in operator to combine up to 10 equality (==) clauses on the same field with a logical OR.

Flutter Firestore Query with arrayContainsAny : List is not working

With latest version of: Flutter + cloud_firestore: ^0.14.0+2
Code:
FutureBuilder(
future: _sessionsLogCollection
.where('companyId', isEqualTo: sPData.companyId)
.where('locationId', arrayContainsAny: [
'29L73oSzdQrzLUow3Mg9',
'bugdWVC6RRtHoemuxNWE',
])
// .where('locationId', isEqualTo: 'bugdWVC6RRtHoemuxNWE')
.orderBy('openDateTime', descending: true)
.get(),
I already have indexes created, so that isn't the problem.
When using .where('locationId', isEqualTo: 'bugdWVC6RRtHoemuxNWE') alone, the query returns the correct data.
But with .where('locationId', arrayContainsAny: ['29L73oSzdQrzLUow3Mg9','bugdWVC6RRtHoemuxNWE']) alone, it does not give any error, but simply returns empty data set: sessionsSnapShot.data.documents.length: 0.
** Solved with .whereIn (Probably .whereIn should be included at firebase.flutter.dev/docs/firestore/usage as it is not currently there)
According to your code .where('locationId', isEqualTo: 'bugdWVC6RRtHoemuxNWE'), it seems that locationId is not an array, instead it is a field. If you want to query an array you can only use arrayContains and arrayContainsAny. But since this is a field then you have to use whereIn:
.where('locationId', whereIn: [
'29L73oSzdQrzLUow3Mg9',
'bugdWVC6RRtHoemuxNWE',
])
Use the in operator to combine up to 10 equality (==) clauses on the same field with a logical OR. An in query returns documents where the given field matches any of the comparison values
https://firebase.google.com/docs/firestore/query-data/queries#array_membership
https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/lib/src/query.dart#L393

Resources