我有一个应用程序,每5秒左右就会有新的孩子被添加到Firebase.我有成千上万的孩子.
在应用程序加载时,我想要处理最初的数千个,而不是每隔5秒钟处理一次的后续子节点.
您可能建议我使用值,处理所有内容,然后使用children_added.但我相信如果处理时间过长,我有可能错过一点.
有没有办法在Firebase中做到这一点,保证我不会错过任何一点?
我正在尝试为我的网站管理员创建简单的通知系统,我只需要向每个管理员用户发送实时消息.但是当我使用firebase时,它会在每个页面上加载旧数据,并且用户可以看到来自数据库的所有消息.如果我设置limit(1),用户将在每个页面重新加载时看到最后一个通知:
var eventsList = new Firebase('https://*****-messages.firebaseio.com/');
eventsList.on('child_added', function(message) {
var message = message.val();
$.notification(message.message);
});
Run Code Online (Sandbox Code Playgroud)
如何在没有旧通知历史的情况下仅加载新邮件?
我有相当大的数据集,可能有数百万个对象,我需要触发child_added事件并获取最后添加的子节点.但是,无论何时启动服务,它都会为数据集中的每个初始子项触发一次事件.
我该如何避免这种行为?
编辑:
建议的解决方案并没有解决问题 - 在我看来它只是忽略了它.在我的具体情况下,我将对其他对象的唯一引用存储为a name,这value是其他重要数据.记录的优先级设置为我的案例时间戳中的特定数字.我使用它来检索记录以构建时间轴,因此我需要选择使用自定义时间戳保存新对象 - 不仅是当前时间戳..on()事件的监听者child_added完全符合需要,除了在开始时取出所有孩子.在我看来,这个功能在任何大型系列上都绝对没有意义.
我有一个iOS市场应用程序,我正在收听该市场上待售的每件商品的变化.更确切地说,我正在听取该项目上的孩子是否会改变或被移除.
问题是我想要在添加孩子时收听.在Firebase上添加子项时监听的特殊之处在于,当您第一次设置侦听器时,您将获得该节点上的所有兄弟节点.
项目上的孩子不是同一项目的列表,所以我不能听一些时间戳后添加的孩子.我正在考虑做这样的 事情并忽略那些最初的孩子.这似乎是一个很大的浪费,因为我基本上是从Firebase中取出两次.一次,FEventTypeValue一次FEventTypeChildAdded.
我想要收听的项目是在Feed中加载的项目.它很可能是几百件物品,但可能是数千件物品.
你会怎么做?我是否应该忘记所有关于倾听额外孩子的问题,还是有一个合适的解决方案?
编辑(添加示例代码):
这就是我在Firebase上获取特定项目的数据的方法.
var ref = new Firebase('https://<your-Firebase>.firebaseio.com');
ref.child('listings/-KB9ZqLZBEskoUihb-yR').once('value', function(snapshot) {
listing = snapshot.val();
});
Run Code Online (Sandbox Code Playgroud)
在这里,我想听一个新的孩子被添加到该项目时:
ref.child('listings/-KB9ZqLZBEskoUihb-yR').on('child_added', function(snapshot) {
listing[snapshot.key()] = snapshot.val()
});
Run Code Online (Sandbox Code Playgroud)
问题是,监听在该节点上添加的项目会再次获取所有子节点,这似乎是一个巨大的浪费.你会如何应对这种情况?
我创建了这个处理程序来监视正在创建的新子项。这个小技巧会阻止 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);
Run Code Online (Sandbox Code Playgroud)
也就是说,当我在 _roomRef 中的节点上调用 remove() 时,会为已经存在的节点触发 child_ added 。关于为什么以及如何阻止它的任何提示?
我还应该提到,这似乎只有在我删除在列表中已有的其他内容之后创建的内容时才会发生。如果我先删除旧项目,则不会触发 child_ added。
根据Firebase文档:
每个现有子项触发一次ChildAdded,每次将新子项添加到指定路径时再触发一次
所以,我有一个应用程序,每当用户收到新消息时,顶部会弹出一个小横幅.您可能已经猜到,这些消息存储在Firebase中的用户对象中的子项中.所以,这就是问题,当我加载应用程序时,会弹出用户拥有的每条消息.是否可以在添加新孩子时调用此观察事件?我不希望为每个现有的孩子触发它,只有在添加新孩子时才会触发.我不想在核心数据中存储消息引用,并检查每个孩子是否已经存在于核心数据中:/
我将一些数据存储在Firebase数据库中名为"notifications"的节点下.当我向"通知"添加事件观察器并将事件类型设置为".childAdded"时,每次将子项添加到"通知"节点时都会调用完成处理程序,并且每次从"通知"节点删除子项时.首先,我不明白为什么会发生这种情况,因为没有添加任何内容,只是删除了.有没有办法避免这种情况?
如果我无法避免每次删除子项时都执行.childAdded块,那么是否有人检测到它实际上是子删除事件而不是子事件添加事件?如果事件被删除,我想从函数中提前返回.以下是我的参考代码:
//Event observer for notifications
notificationsReference.queryLimited(toLast: 1).observe(.childAdded, with: {
(snapshot) in
//Do some stuff here only on .childAdded
//If the event was child deleted, do nothing
})
Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我正在排队服务器将逐个处理的客户端请求.但我只希望服务器处理30秒的请求.所以我创建了一个客户端推送到服务器的唯一路径child_added.有没有办法在添加子项或任何其他元数据时获取时间戳?
我知道我可以让客户端将时间戳放在值中但我不希望客户端控制该值,因为它可能会导致安全风险.
更新:显然没有firebase控制的时间戳或任何其他元数据附加到节点.下面的答案是错误的.