简体   繁体   English

Swift-如何在Firebase中添加已删除的观察者

[英]Swift - How to add a removed observer in firebase

I have a firebase observer like this 我有一个像这样的火力观察者

    let refHandle = firebaseRef.observe(of: DataEventType.value) { (snapshot) in
            ...
        }

It's working perfectly and at one certain point I am removing this observer because I want it to stop observation until I update the values. 它运行良好,并且在某个时候我要删除此观察者,因为我希望它停止观察直到更新值。 I am doing it by using the refHandle 我正在通过使用refHandle

firebaseRef?.removeObserver(withHandle: refHandle)

Now after updating the values how can I add the same observer again ? 现在,在更新值之后,如何再次添加相同的观察者? Firebase doesn't give any function to add the observer using the refHandle. Firebase没有提供任何使用refHandle添加观察者的功能。 The only function I have is this 我唯一的功能就是这个

firebaseRef?.addObserver(NSObject, forKeyPath: String, options: NSKeyValueObservingOptions, context: UnsafeMutableRawPointer?)

Now how can I get all these values from my previous observer so that I can pass them to this function. 现在如何从以前的观察者那里获取所有这些值,以便可以将它们传递给此函数。

For add an observer in fire base first make database reference of FIR child. 为了在火力基地中增加一个观察员,首先要使FIR子级数据库参考。

eg. 例如。 let dbRef: FIRDatabaseReference = FIRDatabase.database().reference().child("child_name") 让dbRef:FIRDatabaseReference = FIRDatabase.database()。reference()。child(“ child_name”)

add observer like, 添加观察者,例如

dbRef.observe(.value, with: { (snapshot) in
       let child = snapshot.children // return number of child 
  })

For remove observer, 对于删除观察者,

create the handler for that reference, 为该引用创建处理程序,

var handle: UInt = 0
handler = dbRef.observe(.value, with: {(snapshot) in

  snapshot.ref.removeValue(completionBlock: {(error, ref) in

         if (error != nil)
                {
                    print("error is \(error)")
                    return
                }
                else
                {
                    dbRef.removeObserver(withHandle: handle) // remove specific observer
                    dbRef.removeAllObservers()// remove all observer
                    print("child removed successfully")
               }
       })
 })

First I think it's important to say that you don't need, and should not, remove this observer , the reason is that this observer observeSingleEventOf(.value) , as the name would suggest, reads the data only once, and then gets immediately removed. 首先,我认为重要的一点是,您不需要(也不应删除)此观察器 ,原因是该观察器observeSingleEventOf(.value)就是只读取一次数据,然后立即获取它,正如名字所暗示的那样。删除。 This might be ideal if you only need the data to be downloaded once and don't expect it to change so much (or at all) for example. 例如,如果您只需要下载一次数据并且不希望数据有太大(或根本没有)变化,那么这可能是理想的选择。

Also, I would recommend you to add a property at the top, within the class scope, to hold a reference to the Database Reference you would like to read from : 另外,我建议您在类范围的顶部添加一个属性,以保留对您要从中读取的数据库引用的引用:

private let databaseRef: FIRDatabaseReference = FIRDatabase.database().reference().child("childNameGoesHere")

It's definitely useful whenever you need to remove an observer ( observe(.value) , observe(.childAdded) , and so on) at some point. 每当您需要移除观察者( observe(.value)observe(.childAdded)等)时,它绝对有用。

Now, in your case, holding a reference to it would also be the solution, since it seems like you need to add this observer again at some point later. 现在,在您的情况下,对它的引用也将是解决方案,因为似乎您需要稍后再添加此观察器。 And again, as I said, you don't need to remove your observe because it will get triggered only once. 再次,正如我所说,您不需要删除观察,因为它只会被触发一次。 So you can just call again wherever you want by using your databaseRef: 因此,您可以使用databaseRef随时随地再次致电:

databaseRef.observeSingleEvent(of: .value) { (snapshot) in
      // ...your code goes here
}

just like you did in the first place and it would work just fine :). 就像您一开始所做的一样,它将正常工作:)。

UPDATE: 更新:

This is how you would remove an observer, and re-add it later at some point : 这是删除观察者,然后在以后重新添加它的方式:

import Firebase
import UIKit

class YourViewController: UIViewController {

// MARK: Private Properties

// You don't need to write the type of rootRef because it's inferred
private let rootRef = Database.database().reference() 

// MARK: LifeCycle

override func viewWillAppear(_ animated: Bool) {
       super.viewWillAppear(animated)

       // Add your observer
       rootRef.observe(of: .value, with: { (snapshot) in
              // Do your stuff here and store your data somewhere so you can use it later
       })
}

// MARK: User Interaction

func addRootObserver() {

     // here you need to make sure that you don't already have an observer at the same reference, otherwise it would duplicate your data.
      rootRef.removeAllObservers()

      // Add your observer
      rootRef.observe(of: .value, with: { (snapshot) in
              // Do some more stuff here
      })

}

func removeRootObserver() {

      // Remove your observer
      rootRef.removeAllObservers()

}

}

Now you can call your addRootObserver() and removeRootObserver() methods safely whenever you need. 现在,您可以在需要时安全地调用addRootObserver()removeRootObserver()方法。

For the handles, well you could do it using handles too (you would need to hold a reference to it too), but I would say it's more a question of personal preferences but of course it would work too :) 对于句柄,您也可以使用句柄(您也需要持有对它的引用),但是我想说这更多是个人喜好问题,但当然也可以使用:)

Issue is resolved not by using addObserver method but by doing this. 不通过使用addObserver方法解决问题,而是通过解决此问题。

  • Created a snapshot class level of var for snapshot 为快照创建了var的快照类级别

var dataSnapshot: ((DataSnapshot)->Void)? var dataSnapshot:(((DataSnapshot)-> Void)?

  • Saved the snapshot 保存快照

dataSnapshot = { (snapshot: DataSnapshot) in .... } dataSnapshot = {(快照:DataSnapshot)在...中。

  • Set observer using data snapshot 使用数据快照设置观察者

firebaseRef.observe(DataEventType.value, with: dataSnapshot) firebaseRef.observe(DataEventType.value,with:dataSnapshot)

  • Removed the observer 删除观察者

firebaseRef?.removeObserver(withHandle: refHandle) firebaseRef?.removeObserver(withHandle:refHandle)

  • When I needed to add the observer again I just started another observer with the same snapshot 当我需要再次添加观察者时,我只是用相同的快照启动了另一个观察者

  • Set observer using data snapshot 使用数据快照设置观察者

firebaseRef.observe(DataEventType.value, with: dataSnapshot) firebaseRef.observe(DataEventType.value,with:dataSnapshot)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM