我已创建此处理程序以监视正在创建的新子项。这个小技巧阻止了child_added事件在每个页面加载时触发我的代码。相反,它只会在实际添加某些内容时触发。
// Listen for new rooms being created
var first_room_added_after_load = true;
this._roomRef.endAt().limit(1).on('child_added', function(snapshot){
if (first_room_added_after_load) { // we want to skip the first room, because it will already exist
first_room_added_after_load = false;
return;
}
else {
this._onCreateRoom(snapshot);
}
}, this);
也就是说,当我在_roomRef中的一个节点上调用remove()时,会为已经存在的节点触发child_added。关于为什么以及如何阻止它的任何提示?
我还应该提一下,如果我删除了在列表中已有的其他东西之后创建的内容,似乎只会发生这种情况。如果我先删除旧项目,则不会触发child_added。
答案 0 :(得分:4)
您似乎认为endAt()
使用时间戳进行比较,因此它只返回新的子项。但这根本不是它的工作原理。来自Firebase documentation for endAt
:
如果没有提供参数,则结束点将是数据的结尾。
使用您的代码:
this._roomRef.endAt().limit(1)
您正在创建一个设置为始终返回单个子项的查询。条件是在创建查询后创建了子项。
查询就像是Firebase参考中子节点的滑动窗口:它总是包含(最多)一个子节点,即创建查询后创建的子节点。
假设您在创建查询时有这些孩子:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
使用endAt
查询将在child3
之后“生根”。因此,它不会触发child1
,child2
和child3
的任何事件。
假设您添加了一个新孩子:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
查询将为child_added
发送child4
个事件。
现在,如果我们添加另一个孩子:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
child5
该查询将为child_removed
和child4
child_added
触发child5
。请注意,child4
实际上并未从您的Firebase中删除,它只是从查询结果中消失了(因为您要求将结果数量限制为仅一个)。
当我们现在删除最新的孩子时,我们最终会:
child1
child2
child3 <!-- last child present when creating the endAt() query -->
child4
该查询将为child_removed
和child5
child_added
触发child4
。这也是因为您的查询被设置为始终包含(最多)在child3
之后添加的一个节点。
对于新添加的孩子,您似乎只想获得child_added
一次。在这种情况下,我不会在查询中使用limit
,而是将设置房间的时间戳设置为优先级:
this._roomRef.push({
/* whatever properties you need for a room */,
'.priority': Firebase.ServerValue.TIMESTAMP
})
然后你可以简单地以该优先级开始查询。
this._roomRef.startAt(Date.now()).on('child_added', ...
答案 1 :(得分:0)
我为此找到了一个棘手的解决方案。 假设您收到的消息具有以下价值 msg-txt,时间戳,用户标识 当使用child_add获得第一条消息时,您需要将最新的消息时间戳存储到全局变量中,然后对于每个新的chils_add,只需比较两个时间戳即可。
如果消息时间戳>全局时间戳 然后返回该消息,并将其时间戳保存为全局时间戳。
希望这会有所帮助