聊天消息无法正确加载

时间:2018-07-01 14:18:34

标签: ios swift firebase google-cloud-firestore

我试图创建一个聊天消息系统,但是当调用新消息时,旧消息似乎仍然存在。

Error picture here

任何人都可以帮忙吗?此外,有时在创建一个新用户并与另一个用户聊天时。来自另一个用户的消息不会反映在新用户聊天中。

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()
                            }
                    }
        }

1 个答案:

答案 0 :(得分:0)

您正在使用addSnapshotListener,这意味着每当数据库中的相关内容发生更改时,都会调用您的回调。发生这种情况时,您将遍历所有与查询匹配的文档,并将它们添加到视图中。这意味着,如果有多个更改,您将多次添加大多数邮件。

有两种常见的解决方案:

  1. 每次调用回调时清除视图。
  2. 仅在每次调用回调时修改视图以进行更改。

由于效率更高,我们将在下面使用#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文档中的responding to changes