【问题标题】:How to stop the execution of a firebase query observe(eventType:with:)如何停止执行 firebase 查询观察(eventType:with:)
【发布时间】:2021-02-22 16:13:15
【问题描述】:

我尝试查找此内容,但找不到停止执行 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
}

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

【问题讨论】:

    标签: ios swift firebase firebase-realtime-database callback


    【解决方案1】:

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

    Swift 中的句柄 FIRDatabaseHandle aka 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)
    }
    

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

    【讨论】:

      【解决方案2】:

      你可以移除所有的观察者:

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

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

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

      乐于助人!

      【讨论】:

      • 我不想移除所有观察者 我只想移除一个观察者...
      【解决方案3】:

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

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

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

      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中的变化

      【讨论】:

      • 我知道,我正在使用有针对性的参考。这只是举个例子。不过谢谢你的回答。
      • @ParthTamane 你问过如何停止执行 firebase 查询,这个答案显示了如何做到这一点。所以....你的问题回答了吗?如果没有,您能否稍微提炼一下这个问题,以便我们知道哪些部分没有得到回答?
      猜你喜欢
      • 2018-07-04
      • 2019-05-23
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多