我正在尝试快速制作简单的Firebase实时聊天应用程序。我的数据库中有一个节点,存储未读消息的数量/
我有一个自定义的tableview单元格,该单元格具有用于显示未读消息数的标签
class UserCell: UITableViewCell {
var message: Message? {
didSet {
setNumberOfUnreadMessages()
}
fileprivate func setNumberOfUnreadMessages() {
if let partnerId = message?.chatPartnerId(), let selfId = message?.selfId() {
let unreadMessagesRef = Database.database().reference().child("unread-messages").child(selfId).child(partnerId).child("numberOfUnreadMessages")
unreadMessagesRef.observe(.value, with: { (snapshot) in
if let count = snapshot.value as? Int {
self.unreadMessagesCountLabel.isHidden = false
self.unreadMessagesCountLabel.text = String(count)
} else {
self.unreadMessagesCountLabel.isHidden = true
}
print(snapshot)
}, withCancel: nil)
}
}
我的tableView
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as? UserCell
let message = messages[indexPath.row]
cell?.message = message
return cell!
}
func observeUserMessages() {
guard let uid = Auth.auth().currentUser?.uid else { return }
// getting reference to current user's node
let ref = Database.database().reference().child("user-messages").child(uid)
ref.observe(.childAdded, with: { (snapshot) in
let userId = snapshot.key
// getting reference to partners node in user's node
let userMessagesRef = Database.database().reference().child("user-messages").child(uid).child(userId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String:AnyObject] {
let message = Message(dictionary: dictionary)
if let chatPartnerId = message.chatPartnerId() {
self.messagesDictionary[chatPartnerId] = message
}
self.attemptReloadOfTableView()
}
}, withCancel: nil)
}, withCancel: nil)
ref.observe(.childRemoved, with: { (snapshot) in
print(snapshot.key)
self.messagesDictionary.removeValue(forKey: snapshot.key)
self.attemptReloadOfTableView()
}, withCancel: nil)
}
// Big thank to Brian Woong)))))
var timer: Timer?
private func attemptReloadOfTableView() {
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.handleReloadTableView), userInfo: nil, repeats: false)
}
@objc func handleReloadTableView() {
self.messages = Array(self.messagesDictionary.values)
self.messages.sort(by: { (message1, message2) -> Bool in
return (message1.timeStamp?.intValue)! > (message2.timeStamp?.intValue)!
})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
启动我的应用程序时,每个tableView.cell都会显示来自数据库的正确未读消息数。当我开始发送消息时,tableView重新加载并开始显示发件人未读消息的数量,不仅在他的单元格上,而且在所有单元格上。此外,在控制台中,我看到它会在每条即将到来的消息中从数据库获取越来越多的快照。
会发生什么?如何解决这个奇怪的错误?
答案 0 :(得分:0)
let unreadMessagesRefHandle = unreadMessagesRef.observe(.value, with: { (snapshot) in
if let count = snapshot.value as? Int {
self.unreadMessagesCountLabel.isHidden = false
self.unreadMessagesCountLabel.text = String(count)
} else {
self.unreadMessagesCountLabel.isHidden = true
}
print(snapshot)
}, withCancel: nil)
unreadMessagesRef.removeObserver(withHandle: unreadMessagesRefHandle)