Remove observer after value change in Firebase
12,145
This is one of the cases where you need to take an extra step in Swift, since it doesn't realize that you can safely access handle
inside the block.
One way of working around this is:
let ref = Firebase(url: "https://yours.firebaseio.com/")
var handle: UInt = 0
handle = ref.observeEventType(.Value, withBlock: { snapshot in
print(snapshot)
if snapshot.exists() && snapshot.value as! String == "42" {
print("The value is now 42")
ref.removeObserverWithHandle(handle)
}
})
By explicitly initializing the handle
variable, we remove the error from the Swift compiler. But given that the handle will have been set before our block is invoked, we can safely call ref.removeObserverWithHandle(handle)
inside the block.
Comments
-
Eugene G. about 2 years
I have global observer in ViewController and need some different observers inside it for specific values like one below. Is it possible to remove observer after value change once?
var ref = Firebase(url: "https://<FIREBASE-APP>.firebaseio.com/") let handle = ref.observeEventType(.Value, withBlock: { snapshot in //Here VALUE Changes to NEW_VALUE if snapshot.value as! String == NEW_VALUE { //IS IT POSSIBLE TO REMOVE HANDLE HERE???? ...something here } }) //NOT HERE ...ref.removeObserverWithHandle(handle)
-
Jay about 8 yearsThe .value is going to cause an issue as it will return all of the values with the node, which would be a dictionary structure which cannot be compared to a string. Probably a for child in snapshot.children would do it. Also, no need for a handle at all in that if we want to observe one change, just do ref.removeAllObservers inside the block. :-)
-
Frank van Puffelen about 8 yearsGood point on the structure @Jay. But I disagree with calling
ref.removeAllObservers()
. That will (as the name says) remove all observers, which is not the same. Although it may work for this simple snippet, in general I prefer to have a symmetry between adding listeners and removing them, -
Jay about 8 yearsHmm. I like the symmetry aspect. Question for clarification; If you add a .Value observer to a node, that will fire on any add, edit or remove events. If you remove the handle from the that node, you will no longer receive any of those events. Won't ref.removeAllObservers have the same effect?
-
Frank van Puffelen about 8 yearsIf you have a single listener on a ref, then calling
ref.removeObserverWithHandle()
andref.removeAllObservers()
will have the same effect. It'd be a reasonable approach if you're in cleanup-code (a destructor, close() method, etc). But if you're explicitly looking to remove a specific listener, I'd preferremoveObserverWithHandle