如何停止执行firebase查询observe(eventType:with:)



我尝试查找它,但找不到停止执行observe类型的firebase查询的方法。Observe每次在引用处更新数据库时都会进行回调并保持运行。但我想在视图消失时停止运行此回调,并在视图出现时再次开始运行查询。

不幸的是,observe函数返回的是int,而不是任何可以用来停止执行查询的处理程序。

func viewWillDissappear(animated: Bool) {
...
stopQuery()
}
func viewWillAppear(animated: Bool) {
...
startQuery()
} 
func startQuery() {
Database.database().reference().observe(.value) { (snapshot) in
//Rest of callback to be executed only when view will appear and is visible
}
}
func stopQuery() {
//Stop query callback execution started by startQuery
}

注意:我不想要依赖于使用vairble来检查视图是否可见并跳过回调执行的答案。我想强制取消当前正在运行的查询,并在下次出现视图时重新启动它。

您可以删除所有观察者:

Database.database().reference().child("ChildName").child("any sub child if any").removeAllObservers()

这将从该路径中删除所有观察者。(根据您的数据库路径更改代码并删除观察者)

如果您有任何问题,请发表评论。

很乐意帮忙!

您可能忽略或误读了文档。观察者,也称为监听器(can),返回一个句柄,该句柄可用于删除观察者。手柄实际上是一个Int.

它在文档中的Detach Listener下。当视图关闭时,只需使用句柄分离侦听器,即可完成设置。

实际上还有一个如何在文档中添加句柄的例子——代码看起来像这个

refHandle = postRef.observe(DataEventType.value, with: { (snapshot) in
let postDict = snapshot.value as? [String : AnyObject] ?? [:]
// ...
})

然后可以使用removeObserverWithHandle删除refHandle

postRef.removeObserver(withHandle: refHandle)

哦,我在你的问题中注意到了这个代码

Database.database().reference().observe(.value)

这可能不是一个好主意,因为它将向整个数据库中的所有内容添加一个观察者,并且对任何子节点的任何更改都将触发该事件并重新加载所有内容!您最好针对特定节点进行更改

let postsRef = Database.database().reference().child("posts")
self.postHandle = postRef.observe(....

它只会返回postsRef 中的更改

不幸的是,observe函数返回一个int,而不是任何处理程序可用于停止查询的执行。

Swift中的句柄FIRDatabaseHandle(也称为DatabaseHandle)定义为:

typedef NSUInteger FIRDatabaseHandle NS_SWIFT_NAME(DatabaseHandle);

因此,你实际上认为这是一个整数是正确的。但最好将返回的句柄存储到强变量句柄中,这样就可以从stopQuery()函数中停止/删除观察器。

像这样:

// MARK: - Properties
private var handle: DatabaseHandle?
// MARK: - Functions
...
...
func startQuery() {
handle = Database.database().reference().observe(.value) { (snapshot) in
//Rest of callback to be executed only when view will appear and is visible
}
}
func stopQuery() {
//Stop query callback execution started by startQuery.
Database.database().reference()
.removeObserver(withHandle: handle)
}

记住,你需要追踪你的整个路径(即特定的孩子)。,否则你可能无法移除你的观察者。

最新更新