0

I am successfully reading and listening for data changes at a Firebase path users using a DataService singleton class as per function below.

Firebase reference:

REF_USERS = DB_BASE.child("users")

Function attaching/listening to path and escaping:

func getUsers(handler: @escaping (_ name: String, _ discoverable: Bool) -> ()){

   REF_USERS.observe(.value) { (snapshot) in
        guard let usersSnapshot = snapshot.children.allObjects as? [DataSnapshot] else { return }
        for user in usersSnapshot{
            let name = user.childSnapshot(forPath: "name").value as! String
            let discoverable = user.childSnapshot(forPath: "discoverable").value as! Bool

            handler (name, discoverable)
        }
    }

}

I am using the function above in my DiscoverVC as such:

DataService.run.getUsers { (name, discoverable) in
            print("name: \(name), discoverable: \(discoverable)")
        }

How can I remove the observer from my DiscoverVC in my viewWillDisappear function?

I understand that I need to pass a DatabaseHandle in the removeObserver call, how do I build the handle?

override func viewWillDisappear(_ animated: Bool) {

        DataService.run.REF_USERS.removeObserver(withHandle: <#T##UInt#>)
    }
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Roggie
  • 1,157
  • 3
  • 16
  • 40

1 Answers1

1

According to the Firebase documentation on detaching listeners:

When you add a callback block to a reference, a FIRDatabaseHandle is returned. These handles can be used to remove the callback block.

So in your case:

handle = REF_USERS.observe(.value) { (snapshot) in
  ...
}

And then in your viewWillDisappear:

override func viewWillDisappear(_ animated: Bool) {
    DataService.run.REF_USERS.removeObserver(withHandle: handle)
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • that makes sense, but how do I reference `handle` in my `viewWillDisappear` which is in a different `Class` called `DiscoverVC` to that of the callback block which is in a `Singleton Class` called `DataService`? – Roggie Jun 20 '18 at 23:01
  • 1
    You will have to pass the handle from the one class to the other. A quick search show [this tutorial](https://learnappmaking.com/pass-data-between-view-controllers-swift-how-to/), or [this question](https://stackoverflow.com/questions/29734954/how-do-you-share-data-between-view-controllers-and-other-objects-in-swift). But to be honest, that sounds like an antipattern: I'd expect the code that attaches the listener, and the code that removes it, to be in the same class, pretty close to each other. The further apart these two are, the harder it becomes to troubleshoot problems. – Frank van Puffelen Jun 21 '18 at 13:44