我有一个聊天 View Controller 和一个聊天列表
每当我单击聊天列表上的对话时,我都会计算子级的总数并保存聊天大小(消息数)。
但是,观察者函数似乎被调用了两次,弄乱了我的真实聊天大小。
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()
})
如何避免观察函数被调用两次?
更新的问题:
这是我使用的代码..
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
每当单击 showChatDialog 时,它实际上会调用一次,但是当我从另一个客户端发送聊天消息时,观察函数会被调用两次?
我知道聊天客户端会互相调用新消息。因此,当 Firebase 用新消息更新时,我猜它会重新调用观察函数,这意味着它会监听任何更新?
最佳答案
解决方案已更新
最后,通过两种可能的方式找到了答案
观察单一类型
或者删除 FIRDatabaseHandle 观察者
//查看单个 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)
}
两者都确保观察者仅被点击一次
关于ios - Firebase 观察被调用两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41047002/