【发布时间】:2019-07-11 09:47:03
【问题描述】:
我有一个 Firebase 快照侦听器,它检查新文档,将它们添加到数组(collectionView 数据源),然后重新加载 collectionView。但是,我在 collectionView 中得到了重复的单元格。我的 Firestore 集合中目前有 3 个对象,但它们被复制了总共 9 个单元格。
我什至添加了对索引的检查,因此 reloadData 仅在到达数组末尾后发生。以下是相关代码:
messageListener = query.addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error listening for channel updates: \(error?.localizedDescription ?? "No error")")
return
}
snapshot.documentChanges.forEach { change in
if change.type == .added {
for document in snapshot.documents{
....
let newMessage = Message(sender: newSender, messageId: document.documentID, sentDate: date, text: text)
self.messages.append(newMessage)
guard let index = snapshot.documents.index(of: document) else {return}
if index == (snapshot.documents.count - 1) {
self.messagesCollectionView.reloadData()
}
}
}
}
}
它正确地对索引进行倒计时,因此最终达到 2 == 2 以重新加载数据。但是,它会再次启动该过程两次,总共 3 次(3 个对象加载了 3 次,总共 9 个单元格)。知道如何改进此逻辑流程以停止重复吗?
谢谢!!
编辑 1
extension ChatViewController: MessagesDataSource {
func currentSender() -> Sender {
//guard let currentUserID = User.current?.key else {return nil}
let newSender = Sender(id: (User.current?.key)!, displayName: (User.current?.username)!)
return newSender
}
func numberOfSections(in messagesCollectionView: MessagesCollectionView) -> Int {
return 1
}
func numberOfItems(inSection section: Int, in messagesCollectionView: MessagesCollectionView) -> Int {
return messages.count
}
func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
return messages[indexPath.section]
func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
return NSAttributedString(string: MessageKitDateFormatter.shared.string(from: message.sentDate), attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedString.Key.foregroundColor: UIColor.darkGray])
}
func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
let name = message.sender.displayName
return NSAttributedString(string: name, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption1)])
}
func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
let dateString = formatter.string(from: message.sentDate)
return NSAttributedString(string: dateString, attributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .caption2)])
}
}
}
【问题讨论】:
-
您能告诉我们您的代码 numberOfSection、numberOfRow、cellForItem 吗?
-
好的,我更新了编辑,但我仍然遇到问题。我的 numberOfSections 已正确设置为 1,我的 numberOfItems 已设置为我的 array.count。奇怪的是,现在我收藏中的第一条聊天消息只重复了 9 次
-
检查你的 self.messages,我非常怀疑它有 9 个值。这可能是由于追加 newMessage 3 * 3 次(3 个文档更改事件,每个事件在数组中添加 3 条消息)引起的。也许您应该在“for document in snapshot.documents”行之前执行 self.messages.removeAll()?
-
“每个事件在数组中添加 3 条消息”必须是它。我没有意识到这就是正在发生的事情,但现在我明白了这些“变化事件”是什么。有没有更好的方法来设置它?我还添加了 removeAll 并将重复项从 9 个减少到 3 个
-
对于改进它在很大程度上取决于您的规范,您是否要处理更新、删除等情况无论如何,您必须始终在重新填充您的快照文档之前重置您的消息数组,否则它会加起来多次。如果这解决了您的问题,我可以写一个答案,以便您投票和批准吗?
标签: ios swift firebase google-cloud-firestore messagekit