问题
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
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" : "test@yahoo.com",
"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" : "test2@yahoo.com",
"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" : "tester3@yahoo.com",
"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?
回答1:
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.
回答2:
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).
回答3:
Can you try saving toId and fromId as Strings?
let toId = String(user!.id!)
This worked for me once.
来源:https://stackoverflow.com/questions/50146628/loading-chats-from-firebase-swift