BACKGROUND
Hello guys, I am performing a query in Firebase that retrieves a list of messages:
ref.child(\"messages\").on(\"child_add
The messages are retrieved in the order you'd expect. You can easily verify this by adding some additional logging:
ref.child("messages").on("child_added", function(snapshot) {
var message = snapshot.val();
console.log(message.message);
ref.child("users").child(message["user-id"]).once("value", function(userSnapshot) {
console.log(message.message+': '+userSnapshot.val().name);
});
});
The output from this on my recent runs has been:
"Message 1"
"Message 2"
"Message 3"
"Message 2: John Joe"
"Message 1: John Joe"
"Message 3: Alfred"
What you see here in the first three lines is that the messages are in order. But you then start retrieving the user for each of the messages; and those users don't necessarily come back in the order you fired/expected them.
This a very common problem when using AJAX on the web: as soon as network traffic is involved, the order of your code is not necessarily the order in which things happen.
The solution is always the same: don't depend on your code executing in a specific order. For example: you most likely want to display the message in a list in the DOM somewhere.
var ul = document.getElementById('messages');
ref.child("messages").on("child_added", function(snapshot) {
var message = snapshot.val();
var li = document.createElement('li');
li.id = 'msg_'+snapshot.key();
li.innerText = message.message;
ul.appendChild(li);
ref.child("users").child(message["user-id"]).once("value", function(userSnapshot) {
li.innerText = userSnapshot.val().name + ': '+ li.innerText;
});
});
Side note: you might want to consider adding a cache of user names. You'll now be calling out to the database for each message, for each user. This is an O(n^2) operation, so does not scale very well with the number of users.
Repro: http://jsbin.com/zofasi/edit?js,console