FEventType.ChildAdded 事件仅触发一次

Posted

技术标签:

【中文标题】FEventType.ChildAdded 事件仅触发一次【英文标题】:FEventType.ChildAdded event only fired once 【发布时间】:2015-12-01 05:10:39 【问题描述】:

我的 firebase 数据结构如下所示

user
  |__user_id
      |__userMatch
            |__userMatchId
                  |__createdAt: <UNIX time in milliseconds>

自特定时间以来,我正在尝试侦听 userMatch 下的子添加事件。这是我的快速代码:

func listenForNewUserMatches(since: NSDate) -> UInt? 
    NSLog("listenForNewUserMatches since: \(since)")
    var handle:UInt?
    let userMatchRef = usersRef.childByAppendingPath("\(user.objectId!)/userMatch")
    var query = userMatchRef.queryOrderedByChild("createdAt");
    query = query.queryStartingAtValue(since.timeIntervalSince1970 * 1000)
    handle = query.observeEventType(FEventType.ChildAdded, withBlock:  snapshot in
        let userMatchId = snapshot.key
        NSLog("New firebase UserMatch created \(userMatchId)")
    , withCancelBlock:   error in
        NSLog("Error listening for new userMatches: \(error)")
    )
    return handle

发生的事情是事件回调只被调用一次。 userMatch 下的后续数据插入没有触发调用。有点像observeSingleEventOfType

我在 user/some-id/userMatch 下的 firebase 中插入了以下数据:

QGgmQnDLUB
    createdAt: 1448934387867
bMfJH1bzNs  
    createdAt: 1448934354943

这里是日志:

2015-11-30 17:32:38.632 listenForNewUserMatches since:2015-12-01 01:32:37 +0000
2015-11-30 17:45:55.163 New firebase UserMatch created bMfJH1bzNs

bMfJH1bzNs 触发了回调,但没有为稍后添加的QGgmQnDLUB 触发回调。这是非常一致的:打开应用程序后,它只触发第一个事件。不知道我在这里做错了什么。

更新:实际上行为不是很一致。有时回调根本没有被触发,甚至一次都没有。但是由于我坚持since 时间,我应该在调用listenForNewUserMatches 函数时使用。如果我杀死应用程序并重新启动应用程序,回调将被触发(在应用程序启动时调用listenForNewUserMatches),在我杀死应用程序之前的childAdded 事件。这种情况非常一致地发生(对于杀死应用程序之前发生的事件,总是在 kill-restart 应用程序时调用回调)。

更新 2:不知道为什么,但如果我将 queryLimitedToLast 添加到查询中,它现在一直有效。我的意思是,通过将userMatchRef.queryOrderedByChild("createdAt") 更改为userMatchRef.queryOrderedByChild("createdAt").queryLimitedToLast(10),它现在可以工作了。 10 只是我选择的任意数字。

【问题讨论】:

【参考方案1】:

我认为问题出在基于时间的数据的性质上。

您创建了一个查询,上面写着:“Get me all the matchs that occur after now.” 当应用程序正在运行并且新数据像bMfJH1bzNs 这样进入时,这应该可以工作。但是像QGgmQnDLUB 这样的旧数据不会显示出来。

然后当您再次运行时,since.timeIntervalSince1970 已更改为以后的日期。现在,之前的任何对象都不会出现在您的查询中。

当您将查询更改为使用 queryLimitedToLast 时,您避免了此问题,因为您不再根据时间进行查询。现在你的查询是:“把这个位置的最后十个孩子给我。

只要该位置有数据,您就会始终在回调中收到数据。

因此,您要么需要确保since.timeIntervalSince1970 始终早于您期望返回的数据,要么使用queryLimitedToLast

【讨论】:

感谢 cmets。实际上,QGgmQnDLUB(发生在 1448934387867)比bMfJH1bzNs(发生在 1448934354943)快了大约 30 秒。这就是为什么我觉得我没有正确使用 API 或者 Firebase SDK 存在错误。

以上是关于FEventType.ChildAdded 事件仅触发一次的主要内容,如果未能解决你的问题,请参考以下文章

QEventLoop 仅等待本地事件而不是主循环事件

DHTMLX Scheduler Month 仅查看事件计数

setPointerCapture 是不是仅适用于 pointerDown 事件?

php 事件日历PRO:仅在某些p上设置“仅显示每个周期事件的第一个实例(仅影响列表样式视图)”选项

如何使用指针事件仅对滚动事件做出反应?

是否可以仅将错误日志发送到事件中心?