【问题标题】:Firebase crashes with 'listen() called twice for the same query' errorFirebase 崩溃并出现“为同一查询调用两次”错误的“listen()”
【发布时间】:2015-07-23 23:07:42
【问题描述】:

我试图听从建议并在需要时删除监听器并在需要时注册监听器。所以在我的 UIViewController.viewDidAppear 我有以下内容:

let chatRef = messagesRef.childByAppendingPath(chat.objectId!)
var query = chatRef.queryOrderedByChild("createdAt")
if let since = since {
    query = query.queryStartingAtValue(since.timeIntervalSince1970 * 1000)
}
let handle = query.observeEventType(FEventType.ChildAdded, withBlock: completion, withCancelBlock: { (error: NSError!) -> Void in
    println("error listening for new Chat messages: \(error)")
});

在我的 UIViewController.viewWillDisappear() 我有

let chatRef = messagesRef.childByAppendingPath(chat.objectId!)
if chatRef != nil {
    chatRef.removeAllObservers()
}

但是每次第二次进入 ViewController 时程序都会崩溃(进入视图控制器,导航离开,然后返回),并出现以下错误:

*** Assertion failure in -[FPersistentConnection listen:tagId:hashFn:onComplete:], /Users/mtse/Dev/firebase/firebase-client-objc/Firebase/Firebase/Core/FPersistentConnection.m:127
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'listen() called twice for the same query'

如果我不移除观察者并且只在 viewDidLoad 中调用一次 observeEventType 而不是 viewDidAppear,程序运行良好。

即使我删除了观察者,程序也可以正常运行,如果我不做queryOrderedByChildqueryStartingAtValue,则将其添加回来。

那么我在这里做错了什么?

【问题讨论】:

    标签: ios swift firebase


    【解决方案1】:

    免责声明:我为 Firebase 工作

    Firebase 中的侦听器特定于您注册它们的路径或查询。调用 removeAllObservers() 会移除所有观察者,但仅来自该路径

    因此,在您的viewWillDisappear() 中,您需要从查询中删除侦听器,而不是引用。

    query.removeAllObservers()
    

    我们只是在我们的文档中更明确地说明了这一点,并且正在寻找使 API 更直观的方法。

    更新 (20150724)

    事实证明,在 FFirebase 上调用 removeAllObservers() 也应该删除同一位置上查询的所有观察者。它不会删除child() 位置的观察者,但应该适用于您的情况。

    我们正在调查出了什么问题,但您似乎在我们的 iOS SDK 中遇到了错误。一旦我们找到它,我们将发布一个固定版本。与此同时,上述服务(并将继续服务)作为一种有效的解决方法。

    【讨论】:

    • 现在可以使用了。谢谢!所以如果我不使用查询,我应该调用Firebase.removeAllObservers(),如果我使用查询,我应该调用FQuery.removeAllObservers(),并且永远不要同时调用两者。那是对的吗? (如果我两者都做,程序似乎也会崩溃)
    • 您需要删除注册观察者的每个FQuery 和每个Firebase 上的所有观察者。因此,如果您在两者上都注册了观察者,则需要在两者上都删除它们。但是你的 sn-p 只观察查询,所以你只需要调用query.removeAllObservers()
    • 我仍然遇到这个问题。有解决办法吗??我已经尝试在我的所有查询和引用上调用 removeAllObservers,但我仍然得到同样的错误。
    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2022-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多