How to Exclude an Element from a Firestore Query

How to exclude an element from a Firestore query?

After days and days of struggling with this issue, I finally found the answer. I could not solve this without the help of @Raj. Thank you so much @Raj for the patience and guidance.

First off all, according to the answer provided by @Frank van Puffelen in his answer from this post, I stopped searching for a solution that can help me pass two queries to a single adapter.

In this question, all that I wanted to achieve was to query the database to get all the users except one, me. So because we cannot combine two queries into a single instance, I found that we can combine the result of both queries. So I have created two queries:

FirebaseFirestore db = FirebaseFirestore.getInstance();
Query firstQuery = db.collection("users").whereLessThan("uid", uid);
Query secondQuery = db.collection("users").whereGreaterThan("uid", uid);

I'm having a UserModel (POJO) class for my user object. I found not one, but two ways to solve the problem. The first one would be to query the database to get all user objects that correspond to the first criteria and add them to a list. After that, query the database again and get the other user objects that correspond to the second criteria and add them to the same list. Now I have a list that contains all the users that I need but one, the one with that particular id from the queries. This is the code for future visitors:

firstQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
List<UserModel> list = new ArrayList<>();
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
UserModel userModel = document.toObject(UserModel.class);
list.add(userModel);
}

secondQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot document : task.getResult()) {
UserModel userModel = document.toObject(UserModel.class);
list.add(userModel);
}

//Use the list of users
}
}
});
}
}
});

The second approach would be much shorter because I use Tasks.whenAllSuccess() like this:

Task firstTask = firstQuery.get();
Task secondTask = secondQuery.get();

Task combinedTask = Tasks.whenAllSuccess(firstTask, secondTask).addOnSuccessListener(new OnSuccessListener<List<Object>>() {
@Override
public void onSuccess(List<Object> list) {
//This is the list that I wanted
}
});

How to filter out certain documents in a firestore query

You can use the not-in query. Here would be a simple example (taken from the docs):

citiesRef.where('country', 'not-in', ['USA', 'Japan']);

Since you want to query by the ID, you can use firebase.firestore.FieldPath.documentId() as the field name (source)

citiesRef.where(firebase.firestore.FieldPath.documentId(), 'not-in', ['123', '456']);

Alternatively you might try to use the '__name__' field-name (source):

citiesRef.where('__name__', 'not-in', ['123', '456']);
  • Docs for not-in: https://firebase.google.com/docs/firestore/query-data/queries#in_not-in_and_array-contains-any
  • Docs for documentId: https://firebase.google.com/docs/reference/js/firebase.firestore.FieldPath#static-documentid

How to delete document from firestore using where clause

You can only delete a document once you have a DocumentReference to it. To get that you must first execute the query, then loop over the QuerySnapshot and finally delete each DocumentSnapshot based on its ref.

var jobskill_query = db.collection('job_skills').where('job_id','==',post.job_id);
jobskill_query.get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
doc.ref.delete();
});
});

Remove all fields associated linked to a document that I removed on another collection

So I finally did it alone.
First, I had to fetch all the properties where the work is working on, to do this I used array-contains.

let docsProperties = await db.collection('user').doc(id).collection("properties")
.where("workers", "array-contains", workerId).get();

Then I wanted to browse all theses properties and remove the worker. Thought about doing a ForEach first. But the problem is I wanted to use an await .update() with arrayRemove and async methods aren't usable inside ForEach.
So I used promises.

            let promises = [];

docsProperties.forEach(doc => {
promises.push(doc.ref.update({
workers: admin.firestore.FieldValue.arrayRemove(workerId)
})); });
return Promise.all(promises);

arrayRemove is a method from the firebase documentation to remove all the occurences of an element on a following array field.
So I browsed all properties, added all promises and executed them!

worked perfectly, if anyone got questions don't hesitate.

Flutter & Firebase: Remove Item(Map) from Array in firebase

Thanks for your replies, in trying further, it seems that this actually works now:

onPressed: () async {
try {
await Firestore.instance
.collection('users')
.document(futSnap.data.uid)
.collection('trainings')
.document(widget.trainingID)
.updateData(
{
'trainingExercises':
FieldValue.arrayRemove(
[trainingExercises[i]],
)
},
);
} catch (e) {
print(e);
}
},

But to be fair I don't understand completely why, because my understanding was as well as yours, that the information has to match the whole map..? I'm happy that it works, but it would be awesome to understand why :D



Related Topics



Leave a reply



Submit