2

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?

3
  • There is nothing in this code snippet that would cause the observe to be called twice. In order for us to help, be sure to share the minimum code that reproduces the problem. Commented Dec 8, 2016 at 19:33
  • You should explore ObserveSingleEventOfType which will fire once and only once, and does not leave the observer attached to the node. Remember that when you attach an observer to a node, any changes in that node will fire the observer. In this case it could potentially cause an issue as even if you observe, read in your data and remove the observer, if the node changes during that process, the event will fire again. Commented Dec 8, 2016 at 23:03
  • Thanks @Jay I updated the solution according to your suggestion. Commented Dec 9, 2016 at 1:34

1 Answer 1

4

SOLUTION UPDATED

Finally, found the answer with 2 possible ways

  1. ObserveSingleType

  2. 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

Sign up to request clarification or add additional context in comments.

1 Comment

I do not want to remove observer then what is the solution?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.