Search code examples
swiftfirebasefirebase-realtime-databaseobservers

How to removeObserver from Firebase DB reference path using Swift?


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

Solution

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