Fire Base Observers

I have a problem removing the Firebase observer in my code. Here's a breakdown of the structure:

var ref = Firebase(url:"https://MY-APP.firebaseio.com/") var handle = UInt? override func viewDidLoad() { handle = ref.observeEventType(.ChildChanged, withBlock: { snapshot in //Do something with the data } } override func viewWillDisappear(animated: Bool) { if handle != nil { println("Removed the handle") ref.removeObserverWithHandle(handle!) } } 

Now, when I leave the viewcontroller, I see that the “Remote handle” is printed, but when I return to the view manager, my observer is called twice for each event. When I leave and return again, he called three times. Etc. Why is the observer not removed?

I also call ref.setValue("some value") later in the code, can this have anything to do with it?

+8
ios swift firebase
source share
3 answers

I thought that I had this error, but in fact I tried to remove the observers from the wrong link.

ORIGINAL CODE:

 let ref: FIRDatabaseReference = FIRDatabase.database().reference() var childAddedHandles: [String:FIRDatabaseHandle] = [:] func observeFeedbackForUser(userId: String) { if childAddedHandles[userId] == nil { // Check if observer already exists // NOTE: - Error is caused because I add .child(userId) to my reference and // do not when I call to remove the observer. childAddedHandles[userId] = ref.child(userId).observeEventType(.ChildAdded) { [weak self] (snapshot: FIRDataSnapshot) in if let post = snapshot.value as? [String:AnyObject], let likes = post["likes"] as? Int where likes > 0 { self?.receivedFeedback(snapshot.key, forUserId: userId) } } } } func stopObservingUser(userId: String) { // THIS DOES NOT WORK guard let cah = childAddedHandles.removeValueForKey(userId) else { print("Not observing user") return } // Error! I did not add .child(userId) to my reference ref.removeObserverWithHandle(cah) } 

FIXED CODE:

 func stopObservingUser(userId: String) { // THIS WORKS guard let cah = childAddedHandles.removeValueForKey(userId) else { print("Not observing user") return } // Add .child(userId) here ref.child(userId).removeObserverWithHandle(cah) } 
+2
source share

Given April 2015, and the error is still around, I suggest a workaround for the problem:

  • save the link to the descriptors (say, in the dictionary, and before initiating a new observer for the same type of event, check if the observer exists.

Having pens around has a very low size (based on some official comments :)), so it won’t hurt so much.

+1
source share

Observers should be removed on the same control path that they were placed on. And for the same number of times, they were released or used ref.removeAllObservers () for each path.

Here is the trick I use to keep it in order:

 var fbObserverRefs = [FIRDatabaseReference]() // keep track of where observers defined. 

... then put the observers in viewDidLoad ():

 fbObserverRefs.append(ref.child("user/\(uid)")) fbObserverRefs.last!.observe(.value, with: { snap in // do the work... }) 

... then, in viewWillDisappear (), take care to remove any released watchers:

 // Only true when popped from the Nav Controller stack, ignoring pushes of // controllers on top. if isBeingDismissed || isMovingFromParentViewController { fbObserverRefs.forEach({ $0.removeAllObservers() }) } 
0
source share

All Articles