Reputation: 737
I have a Chat ViewController and a ChatList
Whenever I click the conversation on the ChatList I count the total children and save the chat size (number of messages).
However, it seems that the observer function is called twice and messes up my real chat size.
let messagesChannelRef = mainChannelRef.child(channelid).child("messages")
messagesChannelRef.observe(FIRDataEventType.value, with: { (snapshot: FIRDataSnapshot) -> Void in
UserDefaults.standard.set(snapshot.childrenCount, forKey: "latestreadchatsize@\(channelid)")
UserDefaults.standard.synchronize()
})
How can I avoid the observe function called twice?
UPDATED QUESTION:
Here is the code the way I use..
class ChannelListTableViewController: UITableViewController {
...........
...........
private lazy var channelRef: FIRDatabaseReference = FIRDatabase.database().reference().child("channels")
..........
func showChatDialog(channelObj: Channel){
let navChatVc: UINavigationController = self.storyboard?.instantiateViewController(withIdentifier: "navChatView") as! UINavigationController
let chatVc : ChatViewController = navChatVc.viewControllers.first as! ChatViewController
chatVc.senderDisplayName = senderDisplayName
chatVc.channel = channelObj
chatVc.channelRef = channelRef.child(channelObj.id)
let channelid = channelObj.id
let messagesChannelRef = channelRef.child(channelid).child("messages")
self.present(navChatVc, animated:true, completion: { () -> Void in
let channelid = channelObj.id
channelRef.child(channelid).child("messages").observe(FIRDataEventType.value, with: { (snapshot: FIRDataSnapshot) -> Void in
UserDefaults.standard.set(snapshot.childrenCount, forKey: "latestreadchatsize@\(channelid)")
UserDefaults.standard.synchronize()
})
})
}
...........
...........
} //end of class
Whenever the showChatDialog is clicked it actually calls once but when I send a chat message from another client, then the observe function is called twice?
I know that the chat clients invoke each other for new messages. So when the Firebase is updated with new messages, I guess it reinvokes the observe function which means it listens for any update?
Upvotes: 2
Views: 2867
Reputation: 737
SOLUTION UPDATED
Finally, found the answer with 2 possible ways
ObserveSingleType
Or Remove the FIRDatabaseHandle observer
//check total message size of a single channel
//you can choose one of these 2 ways
let mainChannelRef: FIRDatabaseReference = FIRDatabase.database().reference().child("channels")
//1st way
if let channelid = channel?.id {
mainChannelRef.child(channelid).child("messages").observeSingleEvent(of: .value, with: { (snapshot) in
UserDefaults.standard.set(snapshot.childrenCount, forKey: "latestreadchatsize@\(channelid)")
UserDefaults.standard.synchronize()
})
}
//2nd way
if let channelid = channel?.id {
let newRefHandle: FIRDatabaseHandle = mainChannelRef.child(channelid).child("messages").observe(FIRDataEventType.value, with: { ( snapshot: FIRDataSnapshot) -> Void in
UserDefaults.standard.set(snapshot.childrenCount, forKey: "latestreadchatsize@\(channelid)")
UserDefaults.standard.synchronize()
})
mainChannelRef.child(channelid).child("messages").removeObserver(withHandle: newRefHandle)
}
Both of them make sure the observer is clicked only once
Upvotes: 4