child_changed 事件仅提供有关哪个直接子级已更改的信息。如果数据结构中更深的节点发生更改,您将知道哪个直接子节点受到影响,但不知道更改数据的完整路径。这是设计使然。
如果您想要精确更新更改的内容,您应该递归地将回调附加到您关心的所有元素。这样,当一个项目发生变化时,你就会知道该项目是由哪个回调触发的。Firebase 实际上针对这个用例进行了优化;附加大量的回调——甚至数千个——应该可以正常工作。在幕后,Firebase 将所有回调聚合在一起,并且只同步所需的最少数据集。
因此,对于您的示例,如果您想在每次为任何用户添加新项目时收到警报,您可以执行以下操作:
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());
});
});
如果您正在处理大量用户(数十万或数百万),并且同步所有数据是不切实际的,那么还有另一种方法。与其让您的服务器直接监听所有数据,不如让它监听一系列更改。然后,当客户端将项目添加到他们的项目列表中时,他们也可以将项目添加到此队列中,以便服务器知道它。
这是客户端代码的样子:
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);
然后,您可以让服务器在该队列上侦听 child_add 并在事件进入时处理它们。