With removeObserver(withHandle in Swift 3, the Observer is not removed on viewDidDisappear
var query = FIRDatabaseQuery()
var postRef: FIRDatabaseReference!
var postRefHandle: FIRDatabaseHandle?
override func viewDidLoad() {
super.viewDidLoad()
postRef = baseRef.child("Posts")
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if postRefHandle != nil {
//try 1:
//postRef.removeObserver(withHandle: postRefHandle!)
//try 2:
//postRef.queryOrdered(byChild: "sortTimestamp").removeObserver(withHandle: postRefHandle!)
//try 3:
//query.removeObserver(withHandle: postRefHandle!)
}
//try 4:
//postRef.removeAllObservers() //works
}
func getPosts()
{
var count = 20
query = postRef.queryOrdered(byChild: "sortTimestamp")
postRefHandle = query.queryLimited(toFirst: UInt(count)).observe(.childAdded //etc.
}
So I tried the three methods in viewDidDisappear, but the observer is not removed. try 3 query.removeObserver(withHandle: postRefHandle!) as by answer from Firebase, how do I return a handle so that I can call removeObserver? by frank-van-puffelen
The only one that does work is the one outlined in try 4. Any reason why I cannot remove the Observer with removeObserver(withHandle? (try 1 - 3)
Also "query.queryLimited(toFirst: UInt(count)).observe(.childAdded" does not get the latest data from Firebase. I was under the impression the observe always gets the updated data, as opposed to observeSingleEvent. Why does it not do that?
Any suggestions are much appreciated.
If you have the following code:
var postsRef: FIRDatabaseReference!
var postRefHandle: FIRDatabaseHandle!
var query = FIRDatabaseQuery()
func addHandler() {
self.postsRef = self.ref.child("posts")
var count = 20
self.query = self.postsRef.queryOrdered(byChild: "sortTimestamp")
self.postRefHandle = self.query.queryLimited(toFirst: UInt(count)).observe(.childAdded, with: { snapshot in
print(snapshot)
})
}
and at a later time you do this function
self.postsRef.removeObserver(withHandle: self.postRefHandle!)
It removes the observer. This is tested code.
To the second part of your question: querySingleEvent and observe do the same thing data wise but have different behaviors. They will both always get current data - modified by startAt, endAt, equalTo etc.
observeSingleEvent returns the data, does NOT leave an observer so you will not be notified if that data changes
observe returns the data and leaves an observer attached to the node and will notify you of future changes.
.childAdded: when any children are added to the node .childChanges: when any children change in the node .childRemoved: when a child is removed.
How I'm Able to Achieve this is by removing child reference.
var recentRef: FIRDatabaseReference!
recentRef.child("\(groupId)").observe(.value, with: { (snapshot) in
recentRef.removeAllObservers() // not_working
recentRef.child("\(groupId)").removeAllObservers() //working
if let obj = snapshot.value as? [String: AnyObject] {
//... code here
}
})
You can achieve this without making a query also(Swift 4) - This removes the reference of the observer properly and works for me.
private let ref = Database.database().reference().child("classTalks")
private var refHandle: DatabaseHandle!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear()
refHandle = ref.observe(.value, with: { (snapshot) in
...
})
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear()
ref.removeObserver(withHandle: refHandle)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With