Firebase: Query to Exclude Data Based on a Condition

Firebase: Query to exclude data based on a condition

I think I've found the solution and this is more of how the database should be designed and actually now I understood the intention behind Firebase guideline

https://firebase.google.com/docs/database/android/structure-data

Original Design:

{
child1: {
"user": {
"id": "id1",
"name": "puf"
}
},
child2: {
"user": {
"id": "id2",
"name": "abe"
}
},
child3: {
"user": {
"id": "id1"
"name": "puf"
}
}
}

Updated Design:

So apart from the storing the id and name of the user, we should also store a node with the id itself as the key and mark it to true

{
child1: {
"user": {
"id": "id1",
"name": "puf"
"id1": true
}
},
child2: {
"user": {
"id": "id2",
"name": "abe"
"id2": true
}
},
child3: {
"user": {
"id": "id1"
"name": "puf"
"id1": true
}
}
}

With the updated design, if i execute ref.orderByChild('user/id1').equalTo(true)

I would get output as Child1 and Child 3

and if i execute ref.orderByChild('user/id1').equalTo(null),

I would get Child2 as the output

Firebase query: exclude data where a specific field is null

If you're trying to exclude items that don't have a property, you need to query for the broadest range of values possible.

A simple example would be:

ref.orderByChild('profile_picture').startAt('!').endAt('~')‌​

This will capture most keys that consist of ASCII characters, since ! is the first printable character (#33) and ~ is the last printable character (#126). Be careful with these, because they won't work when your keys consist of unicode characters.

Firebase Android - how to query not equals

Unfortunately Firebase doesn't provide a method to exclude values in a query, only include (using equalTo()). It is possible to detect the absence of a property though.

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
}
});

Exclude document from query

You're using snapshot.documents, which is a List<DocumentSnapshot> object. So what you're looking for is a way to derive another list from snapshot.documents with some of the documents removed.

My initial search for that flutter filter list, which shows that List.where is what you should be using for that. A simple example on this site: Flutter: Filter list as per some condition

So that'd lead to something like:

QuerySnapshot snapshot = await cardRef.limit(10).getDocuments();
List<DocumentSnapshot> filtered = snapshot.documents.where((doc) => ... /* your filter goes here */ )
List<CustomCard> cards = filtered.map((doc) => CustomCard.fromDocument(doc)).toList();


Related Topics



Leave a reply



Submit