Я попытался создать систему сообщений чата, но старые сообщения, кажется, все еще остаются, когда вызываются новые сообщения.

Кто-нибудь может помочь? Кроме того, иногда, когда создается новый пользователь, и он общается с другим пользователем, сообщения от другого пользователя не отражаются в чате нового пользователя.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationItem.title = "Chat"
DispatchQueue.global(qos:.userInteractive).async {
DispatchQueue.main.async {
self.loadPosts()
self.loadPostsReceivedMessage()
}
}
}
//Get Message sent
func loadPosts() {
let senderIDNumber = Auth.auth().currentUser?.uid
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 documents = querySnapshot?.documents else {
print("Error fetching documents: \(error!)")
return
}
for document in documents {
let messageText = document.data()["message"] as? String
let senderIDNumber = document.data()["senderID"] as? String
let receiverIDNumber = document.data()["receiverID"] as? String
let timestamp = document.data()["timestamp"] as? String
guard let sender = document.data()["sender"] as? String else {return}
// let conversationsCounter = document.data()["conversationsCounter"] as? Int
guard let profileUrl = document.data()["profileUrl"] as? String else { return}
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()
}
}
}
//Get message received
func loadPostsReceivedMessage() {
/* let uid = Auth.auth().currentUser?.uid
let ref = Database.database().reference()
ref.child("users").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
if let dic = snapshot.value as? [String: AnyObject]{
let currentUser = dic["username"] as? String
let senderIDNumber = Auth.auth().currentUser?.uid
} */
let chatsRef = db.collection("chats").order(by: "timestamp", descending: false)
print("thecurrentreceiver"+senderString)
print("thecurrentsender"+receiverIDNumber)
chatsRef.whereField("receiverID", isEqualTo: senderString).whereField("sender", isEqualTo: receiverIDNumber)
.addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("Error fetching documents: \(error!)")
return
}
for document in documents {
let messageText = document.data()["message"] as? String
let senderIDNumber = document.data()["senderID"] as? String
let receiverIDNumber = document.data()["receiverID"] as? String
let timestamp = document.data()["timestamp"] as? String
// let conversationsCounter = document.data()["conversationsCounter"] as? Int
guard let profileUrl = document.data()["profileUrl"] as? String else { return}
guard let sender = document.data()["sender"] as? String else {return}
let chat = Chat(messageTextString: messageText!, senderIDNumber: senderIDNumber!, receiverIDNumber: receiverIDNumber!, timeStampString: timestamp!,profileImageUrl: profileUrl, senderString: sender)
print("whatisthemessage"+messageText!)
self.chats.append(chat)
print(self.chats)
self.chats.sort{$0.timestamp < $1.timestamp}
self.collectionView.reloadData()
}
}
}





Вы используете 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.
Когда я выхожу из чата и снова вхожу в чат, все выглядит нормально. Просто когда я нажимаю кнопку отправки, некоторые сообщения дублируются. При первой загрузке чата старые сообщения тоже выглядят нормально. @IBAction func sendTextMessage (_ sender: Any) {chats.removeAll () self.sendDataToDatabase (message: messageText.text!) MessageText.text = nil self.loadPosts () self.loadPostsReceivedMessage () delayCompletionHandler {self.colatalection () delayCompletionHandler {self.colatalection )}}
Я все еще получаю ту же ошибку, несмотря на попытку вашего кода.