Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell which descendants are changed with on("child_changed")

Tags:

firebase

For example, I have following database structure:

/ 
+ users
  + 1
    + items
      + -xxx: "hello"
  + 2
    + items

Then;

var usersRef = new Firebase("https://mydb.firebaseio.com/users");
usersRef.on("child_changed", function(snapshot) {
  utils.debug(JSON.stringify(snapshot.exportVal()));
});

If a value, "world", is pushed to "/users/1/items", I may get:

{"items": {"-xxx": "hello", "-yyy": "world"}}

So, how to tell which one is changed?

I need to on("child_added") every single ref to "/users/$id/items"?

NOTE: I'm trying to write an admin process in node.js.

like image 961
hiroshi Avatar asked Mar 01 '13 15:03

hiroshi


Video Answer


1 Answers

The child_changed event only provides information on which immediate child has changed. If a node deeper in a data structure changed, you'll know which immediate child was affected but not the full path to the changed data. This is by design.

If you want granular updates about exactly what changed, you should attach callbacks recursively to all of the elements you care about. That way when an item changes, you'll know what the item was by which callback is triggered. Firebase is actually optimized for this use case; attaching large numbers of callbacks -- even thousands -- should work fine. Behind the scenes, Firebase aggregates all of callbacks together and only synchronizes the minimum set of data needed.

So, for your example, if you want to get alerted every time a new item is added for any user, you could do the following:

var usersRef = new Firebase("https://mydb.firebaseio.com/users");
usersRef.on("child_added", function(userSnapshot) {
  userSnapshot.ref().child("items").on("child_added", function(itemSnapshot) 
    utils.debug(itemSnapshot.val());
  });
});

If you are working with a very large number of users (hundreds of thousands or millions), and synchronizing all of the data is impractical, there's another approach. Rather than have your server listen to all of the data directly, you could have it listen to a queue of changes. Then when clients add items to their item lists, they could also add an item to this queue so that the server becomes aware of it.

This is what the client code might look like:

var itemRef = new Firebase("https://mydb.firebaseio.com/users/MYID/items");
var serverEventQueue = new Firebase("https://mydb.firebaseio.com/serverEvents");
itemRef.push(newItem);
serverEventQueue.push(newItem);

You could then have the server listen for child_added on that queue and handle the events when they come in.

like image 167
Andrew Lee Avatar answered Nov 07 '22 02:11

Andrew Lee