例如,我有以下数据库结构:
/
+ 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中编写管理进程。
答案 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);
});