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

How to stop the execution of a firebase query observe(eventType:with:)

提问人:Parth 提问时间:2/23/2021 更新时间:2/23/2021 访问量:406

问:

我尝试查找此内容,但找不到停止执行 firebase 查询类型的方法。Observe 接受回调,并在每次在引用处更新数据库时继续运行它。但是我想在视图消失时停止运行此回调,并在视图出现时再次开始运行查询。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 来检查视图是否可见并跳过回调执行。我想强制取消当前正在运行的查询,并在下次出现视图时重新启动它。

iOS Swift Firebase firebase-realtime-database 回调

评论


答:

2赞 Mohit Kumar 2/23/2021 #1

您可以删除所有观察者:

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

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

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

很乐意为您提供帮助!

评论

0赞 Parth 2/23/2021
我不想删除所有观察者,我只想删除一个观察者......
1赞 Glenn Posadas 2/23/2021 #2

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

Swift 中的句柄 aka 定义为:FIRDatabaseHandleDatabaseHandle

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)
}

请记住,您需要跟踪整个路径(即特定的子路径),否则可能无法删除观察者。

2赞 Jay 2/23/2021 #3

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

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

实际上,文档中还有一个如何添加句柄的示例 - 代码如下所示

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

然后,您可以使用它来删除 refHandleremoveObserverWithHandle

postRef.removeObserver(withHandle: refHandle)

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

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

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

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

这只会返回帖子中的更改Ref

评论

0赞 Parth 2/23/2021
我知道,我正在使用有针对性的参考。这只是举个例子。但谢谢你的回答。
0赞 Jay 2/24/2021
@ParthTamane 您曾问过如何停止 firebase 查询的执行,此答案显示了如何做到这一点。所以。。。。您的问题得到解答了吗?如果没有,您能否稍微完善一下问题,以便我们知道哪些部分没有回答?
0赞 submariner 11/25/2022
我认为我犯了一个错误,现在每一个变化都在观察中解决。如何删除我创建的每个观察点?
0赞 Jay 11/25/2022
@submariner 根据观察者的不同,每个更改都应该生成一个事件。因此,如果您使用的是 .childRemoved,则每次删除儿童时,您的应用都会收到一个事件。同样,如果您使用的是 .value,那么任何类型的每次更改都会显示一个事件。您可以随时删除文档中的所有观察者。不过,根据您评论中的有限信息,这真的很难说。也许发布带有代码的问题和问题描述会按顺序进行?
0赞 submariner 11/26/2022
感谢您的回答@jay您可以在这里找到我的问题 stackoverflow.com/questions/74573935/...