Вы используете addSnapshotListener
, что означает, что ваш обратный вызов вызывается каждый раз, когда что-то релевантное в базе данных изменяется. И когда это происходит, вы перебираете все документы, соответствующие вашему запросу, и добавляете их в свой вид. Это означает, что при наличии нескольких изменений вы добавляете большинство сообщений несколько раз.
Существует два распространенных решения:
- Очистить представление при каждом вызове.
- Изменять представление для изменений можно только при каждом вызове обратного вызова.
Мы будем использовать # 2 ниже, так как он более эффективен. Обратите внимание, что я обрабатываю только новые сообщения, чтобы упростить задачу. По мере того, как вы будете делать ваше приложение более полным, вам также придется обрабатывать другие типы изменений, например, когда пользователь удаляет или обновляет сообщение чата.
let chatsRef = db.collection ("chats").order (by: "timestamp", descending: false)
chatsRef.whereField ("senderID", isEqualTo: senderIDNumber!)
.whereField ("receiverID", isEqualTo: receiverIDNumber)
.addSnapshotListener {
querySnapshot,
error in guard let documentChanges = querySnapshot?.documentChanges else {
print ("Error fetching documents: \(error!)")
return
}
for documentChange in documentChanges {
if (documentChange.type == .added) {
let data = documentChange.document.data ()
let messageText = data["message"] as? String
let senderIDNumber = data["senderID"] as? String
let receiverIDNumber = data["receiverID"] as? String
let timestamp = data["timestamp"] as? String
...
let chat = Chat (
messageTextString : messageText!,
senderIDNumber : senderIDNumber!,
receiverIDNumber : receiverIDNumber!,
timeStampString : timestamp!,
profileImageUrl : profileUrl,
senderString : sender
)
self.chats.append (chat)
print (self.chats)
self.collectionView.reloadData ()
}
}
}
Подробнее об этом см. в ответ на изменения в документации Firebase.