繁体   English   中英

在 Firebase iOS SDK 中,每次删除子项时都会触发 .childAdded。 我怎么能阻止这个?

[英]In Firebase iOS SDK, .childAdded is triggered every time a child is deleted. How can I stop this?

我将一些数据存储在 Firebase 数据库中名为“通知”的节点下。 当我将事件观察器添加到“通知”并将事件类型设置为“.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 
})

Firebase 查询就像数据视图。 在您的情况下,该视图将始终显示基础集合中的最后一项。

说这是你的收藏:

item1
item2

有了这些数据,您的查询最初会为item2触发 child_ item2

现在假设您添加了一个项目:

item1
item2
item3

由于item3现在是集合中的最后一项,因此查询将为 item3 触发 child_ item3

现在您删除item3

item1
item2

由于item2现在再次成为查询中的最后一项,它将为item2触发 child_ item2

有趣的是,我从 Frank 为 JS Firebase SDK 编写的替代答案中找到了处理此问题的正确方法: child_ added 在 remove 后触发 我使用了一种方法,将他的答案从评论修改为他的答案。 特别是 Kato 对如何丢弃 Firebase DB 中的初始数据的回答。

本质上,在这两个答案中,您的子对象中都需要有一个时间戳(或其他一些数字递增的值),以帮助您对子对象进行排序。 然后,当您形成 firebase 查询时,您将设置一个条件,该条件读取此属性超过最小增加值的值。 这样,如果值被删除,它们将不会受到影响,因为它们的排序键将小于传递的键。

对应的 Swift 代码如下所示:

let databaseReference = Database.database().reference().child("messages")
let timeStampKeyInChildObject = "messageTimestamp"

databaseReference
.queryOrdered(byChild: timeStampKeyInChildObject)
.queryStarting(atValue: NSDate().timeIntervalSince1970)
.observe(.childAdded) 

{ (snapshot) in 

  ...


}

就我而言,子对象是聊天消息,其中包含一个名为messageTimestamp的字段。 当我在 firebase 中存储消息时,时间戳是使用NSDate().timeIntervalSince1970 因此,我将此值传递给queryStarting(atValue:)

每次更新数据库时(在这种情况下子删除/添加/修改),只有当删除/添加/修改子的时间戳大于或等于NSDate().timeIntervalSince1970 (其值不断增加)时,才会触发此查询. 这只会发生在当前添加的孩子身上。 任何较旧的(尤其是已删除的)将具有较小的时间戳,并且不会被我们的查询考虑在内。 因此解决了删除导致.childAdded触发器运行的问题。

我选择使用NSDate().timeIntervalSince1970而不是Firebase.ServerValue.TIMESTAMP的 JS 等价物,我认为它是Firebase.ServerValue.timestamp() ,因为它返回[AnyHashable : Any] 我不知道如何解码它。

此外,为了提高性能,将此添加到您的 Firebase RealtimeDB 规则中。 这将在数​​据库端而不是在客户端(下载数据后)进行排序。

"messages": {
    ".indexOn": ["messageTimestamp"]
},

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM