mehmetsen80
mehmetsen80

Reputation: 737

Firebase observe is called twice?

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

Answers (1)

mehmetsen80
mehmetsen80

Reputation: 737

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

Upvotes: 4

Related Questions