Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用Firebase查询重新加载数据后重复collectionView单元格_Ios_Swift_Firebase_Google Cloud Firestore_Messagekit - Fatal编程技术网

Ios 使用Firebase查询重新加载数据后重复collectionView单元格

Ios 使用Firebase查询重新加载数据后重复collectionView单元格,ios,swift,firebase,google-cloud-firestore,messagekit,Ios,Swift,Firebase,Google Cloud Firestore,Messagekit,我有一个Firebase快照侦听器,它检查新文档,将它们添加到数组(collectionView数据源),然后重新加载collectionView。但是,我在collectionView中得到了重复的单元格。我目前在Firebase Firestore集合中有3个对象,但它们在总共9个单元格中被复制 我甚至为索引添加了一个检查,因此只有在到达数组末尾后才会重新加载数据。以下是相关代码: messageListener = query.addSnapshotListener { querySnap

我有一个Firebase快照侦听器,它检查新文档,将它们添加到数组(collectionView数据源),然后重新加载collectionView。但是,我在collectionView中得到了重复的单元格。我目前在Firebase Firestore集合中有3个对象,但它们在总共9个单元格中被复制

我甚至为索引添加了一个检查,因此只有在到达数组末尾后才会重新加载数据。以下是相关代码:

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个对象加载三次,总共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)])
        }
    }
}

消息
在重新填充快照文档之前,必须重置数组。您可以在快照中文档的
行之前添加
self.messages.removeAll()
。文档的

之后必须清除包含对象的数组

collectionView?.refreshControl?.beginRefreshing()
self.messages = []
然后打电话

self.collectionView?.reloadData()

否则,您将出现“索引超出范围”错误

能否显示您的代码numberOfSection、numberOfRow、cellForItem?好的,我更新了编辑,但仍然存在问题。My numberOfSections已正确设置为1,My numberOfItems已设置为My array.count。奇怪的是,我收集的第一条聊天信息只重复了9次检查你的自我信息,我高度怀疑它有9个值。这可能是因为追加了3*3次新消息(3个文档更改事件,每个事件在数组中添加3条消息)。也许您应该在“for document in snapshot.documents”?“每个事件在数组中添加3条消息”这一行之前执行self.messages.removeAll()。我不知道发生了什么,但现在我明白了这些“变化事件”是什么。有没有更好的方法来设置这个?此外,我还添加了removeAll,它将重复项从9减少到了3。这在很大程度上取决于您的规范,是否要处理更新、删除等情况。无论如何,在重新填充快照文档之前,您必须始终重置消息数组,否则它将多次累积。如果这解决了你的问题,我可以写一个答案让你投票赞成吗?