如何判断哪些后代已更改(“child_changed”)

时间:2013-03-01 15:25:10

标签: firebase

例如,我有以下数据库结构:

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

然后;

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

如果某个值“world”被推送到“/ users / 1 / items”,我可能会得到:

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

那么,如何判断哪一个被改变了?

我需要(“child_added”)每一个引用“/ users / $ id / items”吗?

注意:我正在尝试在node.js中编写管理进程。

2 个答案:

答案 0 :(得分:22)

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_added并在事件进入时处理这些事件。

答案 1 :(得分:5)

Andrew Lee给出了一个很好的答案,但我认为你应该尝试使用云功能。这样的事情应该有效:

exports.getPath = functions.database.ref('/users/{id}/items/{itemId}')
.onWrite(event => {
  // Grab the current value of what was written to the Realtime Database.
  const original = event.data.val();
  console.log('user id', event.params.id);
  console.log('item id', event.params.itemId);
});