Firebase 崩溃并出现 'listen() called twice for the same query' 错误

Firebase crashes with 'listen() called twice for the same query' error

我试图听从建议并在需要时删除侦听器并在需要时注册侦听器。所以在我的 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.

那么我做错了什么?

免责声明:我在 Firebase 工作

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

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

query.removeAllObservers()

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

更新 (20150724)

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

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