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
Manually Put Files to Android Emulator Sd Card
How to Pass a View's Onclick Event to Its Parent on Android
How to Add Window -- Token Android.Os.Binderproxy Is Not Valid; Is Your Activity Running
How to Get My Android Device Country Code Without Using Gps
Get List of Photo Galleries on Android
How to Change a Tab Background Color When Using Tablayout
Get Ssid When Wifi Is Connected
Android Maps API V2 with Custom Markers
Preventing Status Bar Expansion
What Will Happen to the Sharedpreferences on Update an Android App
Realmchangelistener Does Not Get Called When Realm Gets Updated in Notificationlistenerservice
How to Use Adb to Send Touch Events to Device Using Sendevent Command
Read & Writing Arrays of Parcelable Objects
Programmatically Getting the Gateway and Subnet Mask Details