I am trying to count the number of children in my DB table that meet a certain condition. If the isSeen
column equals false
then I want to count that, if it equals true
I don’t want to count it.
Currently, it’s not working but if I change the query from Query query = usersRef.orderByChild("isSeen").equalTo(true);
to Query query = usersRef.orderByChild("isSeen");
I get a number but it’s not the correct way. Can someone please help me?
Rules:
{ "rules": { ".read": true, ".write": true, "Messages": { ".indexOn": "isSeen" } } } "Messages": { "b3vYlKZFrje0e3wHyBlWIK4ooK93": { "DIt5bGqw2WS4eGHNqQJKxZSn3B72": { "-N8NCgnwX6V7ghfGlcWS": { "dateAdded": 1659337356887, "date_time": "Aug-01-2022 3:02:36 AM", "from": "DIt5bGqw2WS4eGHNqQJKxZSn3B72", "isSeen": true, "message": "Yoo", "to": "b3vYlKZFrje0e3wHyBlWIK4ooK93", "type": "text" }, "-N99iQjlMfeyOM_VCAEB": { "dateAdded": 1660184797462, "date_time": "Aug-10-2022 10:26:37 PM", "from": "DIt5bGqw2WS4eGHNqQJKxZSn3B72", "isSeen": true, "message": "Wassup", "to": "b3vYlKZFrje0e3wHyBlWIK4ooK93", "type": "text" } } } },
DatabaseReference usersRef = FirebaseDatabase.getInstance().getReference("Messages"); Query query = usersRef.child(firebaseUser.getUid()).orderByChild("isSeen").equalTo(true); query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() { @Override public void onComplete(@NonNull Task<DataSnapshot> task) { if (task.isSuccessful()) { long count = task.getResult().getChildrenCount(); Log.d("TAG1", "count: " + count); } else { Log.d("TAG2", task.getException().getMessage()); //Never ignore potential errors! } } });
Error message:
D/TAG2: Index not defined, add ".indexOn": "isSeen", for path "/Messages/b3vYlKZFrje0e3wHyBlWIK4ooK93", to the rules
Advertisement
Answer
When you’re using the following query:
Query query = usersRef.orderByChild("isSeen").equalTo(true);
Firebase will always return the exact data you are querying, meaning that you’ll get all elements that have the isSeen
field set to true
. Please note that there is no way you can query by a negation. So something like this is not possible:
Query query = usersRef.orderByChild("isSeen").notEqualTo(true); // ð
According to your comment in which you say that you don’t have any elements where the isSeen
field is set to true
, then your query will yield no results, and that’s the expected behavior.
While @TimothyPham’s answer will work, using getChildrenCount()
might be the best solution. Why? Because if you have a lot of messages this operation requires you to read all of them in order to provide a number. The best solution I can think of would be to increment/decrement a counter as explained in my answer from the following post:
Edit:
Query query = usersRef.orderByChild("isSeen").equalTo(true); query.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() { @Override public void onComplete(@NonNull Task<DataSnapshot> task) { if (task.isSuccessful()) { long count = task.getResult().getChildrenCount(); Log.d("TAG", "count: " + count); } else { Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors! } } });
But this code will only work if you have elements in the database that have he isSeen
field is set to true
.