Append Firebase chat messages

时光毁灭记忆、已成空白 提交于 2019-12-25 09:43:02

问题


I am creating a chat app and I have a list of all the messages sent between two users in a table view cell. For example, I have four texts in total between the two users and so I have four cells. However, I would like to group the cells so that I only have one cell, because I the loggedInUser is only communicating with one person. No matter what I do, the messages will not append.

func loadData(){
if (FIRAuth.auth()?.currentUser) != nil{

FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in

let loggedInUserData = snapshot
if let postsDictionary = snapshot .value as? [String: AnyObject] {

for post in postsDictionary {
    let messages = post.value as! [String: AnyObject]
    for (id, value) in messages {
        let info = value as! [String: AnyObject]
        if let receiver = info["ReceiverId"] {
        print("\(id): \(receiver)")
       self.messages.Array(value)

        }

    }
    self.MessageTableView.reloadData()
}


}})}
}

As of now my app is displaying messages between two users like this:

I think the issue is in the self.messages.Array(value) I just need to append messages between the same two users but I can't find the right code

But I would like for a conversation between two users to be in one cell (append it)

This is what my cell looks like:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageTableViewCell


    //Configure the cell


    print(messages[indexPath.row])
    let message = self.messages[indexPath.row] as! [String: AnyObject]
    if let seconds = message["timestamp"] as? Double {
        let timeStampDate = NSDate(timeIntervalSince1970: seconds)
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "hh:mm a"
        cell.Time.text = dateFormatter.string(from: timeStampDate as Date)
    }



    cell.Message.text = message["text"] as? String
   // cell.SellerName.text = message["ReceiverId"] as? String


  if let imageName =  message["ReceiverId"] as? String {

        let ref = FIRDatabase.database().reference().child("posts").child(imageName)

    ref.observeSingleEvent(of: .value, with: { (snapshot)
        in

        if let dictionary = snapshot.value as? [String: AnyObject]{
            for post in dictionary {
                let messages = post.value as! [String: AnyObject]
                for (id, value) in messages {

                cell.SellerName.text = messages["username"] as? String
                    if (messages["uid"] as? String) != nil {
                        let uidPoster = messages["uid"] as? String
                        let imageRef = FIRStorage.storage().reference().child((uidPoster)!+"/profile_pic.jpg")

                        imageRef.data(withMaxSize: 25 * 1024 * 1024, completion: { (data, error) -> Void in
                            if error == nil {

                                let image = UIImage(data: data!)
                                cell.UserPic.image = image

                                cell.UserPic.layer.cornerRadius = 30
                                cell.UserPic.clipsToBounds = true



                            }else {

                                print("Error downloading image:" )


                            }})}

                    self.messages.add(value)
                }
            }


        }

    })
    }

    return cell
}

my path to firebase message is:

FIRDatabase.database().reference().child("messages").child("(self.convoId!)").childByAutoId()

Here is my database structure:


回答1:


I will use a super simple example in my answer.

Given a structure

messages
   msg_0
      rec: "uid_0"
      send: "uid_1"
      msg: "msg from uid_0 to uid_1"
   msg_1
      rec: "uid_1"
      send: "uid_0"
      msg: "msg from uid_1 to uid_0"

Add a query observer to the messages node watching for any new messages (.childAdded) that have a rec: of uid_0.

var messagesArray = [String]()

func watch() {
    let messagesRef = self.ref.child("messages")
    let queryRef = messagesRef.queryOrdered(byChild: "rec").queryEqual(toValue: "uid_0")

    queryRef.observe(.childAdded, with: { snapshot in

        let msgDict = snapshot.value as! [String: Any]
        let msg = msgDict["msg"] as! String

        self.messagesArray = [] //erases the array
        self.messagesArray.append(msg) //adds this new message at index 0

        print(self.messagesArray) //print is just for example
        //normally call tableView.reloadData() which will refresh
        //  the cells in the tableView and display just once cell with
        //  the latest message in it
    })
}

You can extrapolate from this by storing the snapshot or the dictionary in the array so you know the message text and can use the send: user id to look up who sent the message.

If you run this code, the output will be any new message sent to uid_0; only the latest message will be displayed. If you have a tableView with the messagesArray as it's dataSource (which is normally how its done) then the tableView would be refreshed and only ever show the latest message for uid_0.

As a side note, .queryLimited(toLast:) could be leveraged here was well.




回答2:


1) I think, that in your case you should .queryLimited(toLast: 1) to messages to each chat. And if details opened - load other messages.

2) But I have an assumption, that you have wrong database structure. Check this

Here you can find good structure of the database for chat by firebase doc's authors.

Also you can check this old snippets of making chat app: Link

Hope it helps



来源:https://stackoverflow.com/questions/44070005/append-firebase-chat-messages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!