【问题标题】:Chat messages does not load properly聊天消息无法正确加载
【发布时间】:2018-07-01 22:49:18
【问题描述】:

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

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

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

【问题讨论】:

    标签: ios swift firebase google-cloud-firestore


    【解决方案1】:

    您正在使用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

    【讨论】:

    • 尽管尝试了您的代码,但我仍然遇到同样的错误。
    • 当我退出聊天并重新进入聊天时,一切看起来都很好。只是当我点击发送按钮时,一些消息会被重复。当聊天第一次加载时,旧消息看起来也很好。 @IBAction func sendTextMessage(_ sender: Any) { chats.removeAll() self.sendDataToDatabase(message: messageText.text!) messageText.text = nil self.loadPosts() self.loadPostsReceivedMessage() delayCompletionHandler { self.collectionView.reloadData( ) } }
    猜你喜欢
    • 2019-05-02
    • 1970-01-01
    • 2020-11-30
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多