Skip to content
Advertisement

Difference between addChildEventListener, addValueEventListener, and addOnCompleteListener when using orderByChild()?

I’m trying to sort and display data from Firebase using orderByChild() and used:

ref.child("dinosaurs").orderByChild("height").get().addOnCompleteListener(...);

I kept on wondering why it’s not sorting until I realized that childEventListener was used in the documentation. It should’ve been:

ref.child("dinosaurs").orderByChild("height").addChildEventListener(...);

What is the difference between the two and addValueEventListener when it comes to using orderByChild or any sorting method? Does get() not follow orderByChild()?

Advertisement

Answer

All of the methods you describe return the child nodes in the order your query requests.

Most likely you’re calling getValue() on the complete DataSnapshot you get though. Doing so converts the results to a Map and (by definition) the order of the keys in a map is undefined.

When you’re using addChildEventListener, your onChildAdded gets called for each individual child snapshot in order already, so you have no way to make this mistake.

To process the resulting child nodes in the order you requested them in onDataChange and when using get(), you need to loop over getChildren() of the DataSnapshot you get back, as shown in the documentation on listening for value events on a list of children.

So something like:

ref.child("dinosaurs").orderByChild("height").get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (!task.isSuccessful()) {
            Log.e("firebase", "Error getting data", task.getException());
        }
        else {
            DataSnapshot snapshot = task.getResult();
            for (DataSnapshot childSnapshot: snapshot.getChildren()) {
                Log.i("FIREBASE", childSnapshot.getKey());
            }
        }
    }
});

Advertisement