orderByChild not working in Firebase

JohnAndrews picture JohnAndrews · Nov 24, 2015 · Viewed 20.7k times · Source

I am trying to query my database such that it retrieves an ordered list based on a child key. I do it as follows (see below), but nothing happens, meaning that it returns an object ordered exactly in the same way as it is stored in the Firebase database. What is going on?

self.getAllProfiles = function () {
    var qProfile = $q.defer();
    var ref = new Firebase(FBURL);
    ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
        console.log(snapshot.val()) // HERE IS WHERE IT SHOULD BE ORDERED
        qProfile.resolve(snapshot.val());
    }, function (errorObject) {
        qProfile.reject(errorObject);
    });
    return qProfile.promise;
};

To add, my users node looks as follows:

users
   /$username
       /last_update
       /id
       /data
          /profile_image
          /display_name

Here is a snapshot:

Tester: Object
   github: Object
   last_update: 1447732462170
   userId: "github:12345"

Answer

Frank van Puffelen picture Frank van Puffelen · Nov 24, 2015

When you call snapshot.val(), you are getting back a JSON object. The order of keys in a JSON object is determined by your browser and not by Firebase.

To get the children in order:

self.getAllProfiles = function () {
    var qProfile = $q.defer();
    var ref = new Firebase(FBURL);
    ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
        snapshot.forEach(function(child) {
            console.log(child.val()) // NOW THE CHILDREN PRINT IN ORDER
        });
        qProfile.resolve(snapshot.val());
    }, function (errorObject) {
        qProfile.reject(errorObject);
    });
    return qProfile.promise;
};

You can leave the q.resolve() call where it is: snapshot.forEach() is not an asynchronous call.