0

I have "orderStatus" node type integer in my database, and I need to query it by its value(0, 1, 2, etc.). It works okay if I user orderByChild("orderStatus"), but I don't want to be downloading all data and order it, I just want to download data with specific "orderStatus". That's where I run to my problem, when I put equalTo(statusInteger) I don't get any data from the database. What am I doing wrong, am I using equalTo wrong or something?

DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Orders");
Query orderRef = databaseReference
            .child(restaurantId)
            .orderByChild("orderStatus")
            .equalTo(0);
orderRef.addListenerForSingleValueEvent...

Database Screenshot

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Dorian Pavetić
  • 123
  • 1
  • 8
  • Firebase query work on a flat list of nodes. The value you order/filter on must be at a fixed path under each direct child node of the location where you run the query. So if you have the path `/Orders/restaurant01/LPGbh....xCQ2`, you can query the `orderStatus` under there. But you can't query all orders under `/Orders/restaurant01` as the value is not at a fixed path under each direct child node (and in fact, there may be multiple values under each direct child node). The solution is to create a flat list of orders. See https://stackoverflow.com/q/27207059 – Frank van Puffelen Dec 02 '20 at 15:55

2 Answers2

0

what if you Start with .equalTo(... ) then .orderBy(...)?

Khoudnami
  • 56
  • 4
0

To be able to query the database by a specific property, you need to add all child names that exist in that particular hierarchy. In your query, you are missing a child. Between the "restaurantId" node and the actual Order object, which holds the "orderStatus" property, there is one more node, which is "LPG ... CQ2", and I'm assuming the UID of the logged-in user. To make it work, please use the following lines of code:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("Orders").child("Restaurant01").child(uid);
Query orderStatusQuery = uidRef.orderByChild("orderStatus").equalTo(0);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String userName = ds.child("userName").getValue(String.class);
            Log.d("TAG", userName);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
    }
};
orderStatusQuery.addListenerForSingleValueEvent(valueEventListener);

The result in the logcat will be:

User

Edit:

According to your comment, what you are looking for it's actually not possible with your actual database structure. Besides that, filtering on the client it's definitely not an option in this scenario.

However, the best I can think of is to create another node that stores all orders, of all users. In this way, you can query using ".orderByChild("orderStatus").equalTo(0)" and you'll get the desired results. This practice is called denormalization and is a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Realtime Database.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • The problem is that this Query happends on Server App and I want to get all orders with "orderStatus" 0 of all users, so I don't have userID. Yes, you may say I could filter it on client side, but lets say there is 1000 orders and only 10 is "orderStatus" 0, I don't want to download all 1000 and filter then client side... – Dorian Pavetić Dec 02 '20 at 14:25
  • I see, in this case, please see my updated answer. – Alex Mamo Dec 02 '20 at 14:41