William Loke
William Loke

Reputation: 377

loading chats from firebase Swift

I am doing a chat messenger currently and I am able to retrieve all the messages I sent to another user but not able to retrieve whatever they sent. The codes i used to load my messages is

func loadMsg() {
    let toId = user!.id!
    let fromId = Auth.auth().currentUser!.uid
    let ref = Database.database().reference().child("privateMessages").child(fromId).child(toId)
    ref.observe(.value) { (snapshot) in

        if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {

            self.messages.removeAll()

            for data in snapshot {

                let newMsg = Message(dictionary: data.value as! [String: AnyObject])

                self.messages.append(newMsg)

            }
        }
        DispatchQueue.main.async {self.tableView.reloadData()}
    }
}

as for my firebase database, it looks like enter image description here

and the json file of

{
  "privateMessages" : {
    "0YfqnPIOYFYKb8cYZMHnSYti62i2" : {
      "StHPXFvTlVf5QDvWiuCi4JF8Hyr2" : {
    "-LB0AZRcWF0Ub5ZECzTf" : {
      "fromId" : "0YfqnPIOYFYKb8cYZMHnSYti62i2",
      "textMessages" : "Hi!first msg!",
      "timestamp" : 1524733200,
      "toId" : "StHPXFvTlVf5QDvWiuCi4JF8Hyr2"
    }
  },
  "kj7vcszbSvPBTVaC32Xg18aYZPi1" : {
    "-LB0EpR86dZSYl5p0k-E" : {
      "fromId" : "0YfqnPIOYFYKb8cYZMHnSYti62i2",
      "textMessages" : "Different guy,message 2",
      "timestamp" : 1524734318,
      "toId" : "kj7vcszbSvPBTVaC32Xg18aYZPi1"
    }
  }
},
"2wYq9dCKF4aZ26nOY41ApPOdGrJ2" : {
  "0YfqnPIOYFYKb8cYZMHnSYti62i2" : {
    "-LBV5jlvtxbZZJFQOwes" : {
      "fromId" : "2wYq9dCKF4aZ26nOY41ApPOdGrJ2",
      "textMessages" : "hi",
      "timestamp" : 1525252029,
      "toId" : "0YfqnPIOYFYKb8cYZMHnSYti62i2"
    }
  },
  "StHPXFvTlVf5QDvWiuCi4JF8Hyr2" : {
    "-LBVCQ5GaEugMNFMT2c-" : {
      "fromId" : "2wYq9dCKF4aZ26nOY41ApPOdGrJ2",
      "textMessages" : "hi",
      "timestamp" : 1525253780,
      "toId" : "StHPXFvTlVf5QDvWiuCi4JF8Hyr2"
    }
  }
},
"StHPXFvTlVf5QDvWiuCi4JF8Hyr2" : {
  "0YfqnPIOYFYKb8cYZMHnSYti62i2" : {
    "-LBVGEFG76z6tXtq43k5" : {
      "fromId" : "StHPXFvTlVf5QDvWiuCi4JF8Hyr2",
      "textMessages" : "Hi",
      "timestamp" : 1525254780,
      "toId" : "0YfqnPIOYFYKb8cYZMHnSYti62i2"
    }
  }
}
  },
  "users" : {
"0YfqnPIOYFYKb8cYZMHnSYti62i2" : {
  "email" : "[email protected]",
  "id" : "0YfqnPIOYFYKb8cYZMHnSYti62i2",
  "name" : "tester",
  "profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/groupchatnappointment.appspot.com/o/profile_images%2FE509EFCB-E41D-4E6C-922B-01B146FD1FDC.png?alt=media&token=a7acb904-474b-4898-b99a-1e819ec96afc"
},
"StHPXFvTlVf5QDvWiuCi4JF8Hyr2" : {
  "email" : "[email protected]",
  "id" : "StHPXFvTlVf5QDvWiuCi4JF8Hyr2",
  "name" : "tester2",
  "profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/groupchatnappointment.appspot.com/o/profile_images%2F2A5009D7-51C4-4D95-88DF-DADB38C76E7B.png?alt=media&token=ae599135-8ff7-4c64-9667-b9a5cec3dcf8"
},
"kj7vcszbSvPBTVaC32Xg18aYZPi1" : {
  "email" : "[email protected]",
  "id" : "kj7vcszbSvPBTVaC32Xg18aYZPi1",
  "name" : "tester3",
  "profileImageUrl" : "https://firebasestorage.googleapis.com/v0/b/groupchatnappointment.appspot.com/o/profile_images%2FD60F2433-14E2-4EE1-AA74-8171CBA1D3AD.png?alt=media&token=728f6171-e48d-4bae-9b84-007937ed3493"
    }
  }
}

and my tableviewCells has a config function of

func configCell(message: Message) {

    self.message = message

    if message.fromId == currentUser {

        sentView.isHidden = false

        sentMsgLabel.text = message.textMessages

        receivedMsgLabel.text = ""

        receivedMsgLabel.isHidden = true

    } else {

        sentView.isHidden = true

        sentMsgLabel.text = ""

        receivedMsgLabel.text = message.textMessages

        receivedMsgLabel.isHidden = false
    }
}

how should i attempt as to be able to show both what my recipient sent to me and what I have sent to them in my chat logs?

Upvotes: 2

Views: 2053

Answers (3)

Frank van Puffelen
Frank van Puffelen

Reputation: 598817

Typically in chat apps, I model the data as "chat rooms". So if there is a chat between two individuals, I create a node for that conversation.

This looks really similar to your data structure, but now with a single node for the "room". When possible I like to base the room id on the UIDs of the participants (for more on this see http://stackoverflow.com/questions/33540479/best-way-to-manage-chat-channels-in-firebase). So in your case:

privateChats
  0YfqnPIOYFYKb8cYZMHnSYti62i2_StHPXFvTlVf5QDvWiuCi4JF8Hyr2
    -LB0AZ...CzTf
      ...
    -LB0F1...pvyJ
      ...

With this structure, you can easily show the entire conversation between the two users by looking up their room and then simply listing the messages.

For the "list of conversations" for a user, I then model an additional node for each user:

chatsPerUser
  0YfqnPIOYFYKb8cYZMHnSYti62i2
          0YfqnPIOYFYKb8cYZMHnSYti62i2_StHPXFvTlVf5QDvWiuCi4JF8Hyr2: ...
  StHPXFvTlVf5QDvWiuCi4JF8Hyr2    
          0YfqnPIOYFYKb8cYZMHnSYti62i2_StHPXFvTlVf5QDvWiuCi4JF8Hyr2: ...

In here you can keep whatever information you need to display the list of conversations, such as the "room name" (only commonly used for rooms with >2 participants) or the timestamp of the latest message (useful for showing the conversations in chronological order).

Upvotes: 2

TheTiger
TheTiger

Reputation: 13354

Actually your node is wrong here .child(fromId).child(toId) this way you can fetch only one side messages.

let chatRoomId = (fromId < toId) ? fromId + "_" + toId : toId + "_" + formId 
/// It will look like "0YfqnPIOYFYKb8cYZMHnSYti62i2_kj7vcszbSvPBTVaC32Xg18aYZPi1"

And then store all the messages here and when need to fetch make the chatRoomId in same way. This way you can easily fetch all the chat b/w these two users. I have also answered for paging. So have a look at Firabase Paging and load messages in chunks. It will make the better user experience.

Upvotes: 2

Raghav Grandhi
Raghav Grandhi

Reputation: 66

Can you try saving toId and fromId as Strings?

let toId = String(user!.id!)

This worked for me once.

Upvotes: 0

Related Questions