问题
First off, if you have a suggestion for a better title or actual question for this submission, please feel free to edit. I'm stuck as to how to succeed in asking this question.
So I've made gone through several Firebase chat (iMessage/ Facebook chat) tutorials for swift. I know how to send a message -
let ref = Database.database().reference().child("Message")
let childRef = ref.childByAutoId()
let toID = finalSelected.ContactID as Any
let fromID = Auth.auth().currentUser?.uid
let values = ["Message": messageTextField.text!, "toID": toID, "fromID": fromID!] as [String: Any]
childRef.updateChildValues(values) { (error, ref) in ...
and I know how to retrieve them -
let messagesOf = Auth.auth().currentUser?.uid
let messageDB = Database.database().reference().child("Message")
let userMessages = messageDB.queryOrdered(byChild: "toID").queryEqual(toValue: messagesOf)
userMessages.observeSingleEvent(of: .childAdded, with: { (snapshot) in
let values = snapshot.value as! Dictionary<String, String>
let message = values["Message"]
let from = values["fromID"]
let post = ChatMessages()
post.aMessage = message!
post.Interested = from!
self.messagesArray.append(post)
self.tableView.reloadData()
})
However, I'm having a difficult time finishing the logic. I don't understand how these two separate events combine into one identical end result - not two different transactions. Let me see if I can explain it further...
I send a message. I then receive this message as another user. But I do not understand how the to/from data is downloaded that references both simultaneously. Unless I'm looking overlooking some detail, doesn't the single or plural observation of an event only apply to one user? Or am I misunderstanding some concept here?
Help with this final concept would be fantastic. Thank You.
回答1:
You now have a single list of chat messages, which is very similar to how you'd model this in a relations database. But Firebase is a NoSQL database, so you have better options for modeling chat.
The most common solution is to model chat rooms into your database. So if two users are chatting, then the messages between those two users will be in a "room node". And if two other users are also chatting, their messages will be in a separate room. The data model for this will look like:
chats: {
roomid1: {
messageid1: {
fromId: "UidOfSender1",
message: "Hello there user 2!"
},
messageid2: {
fromId: "UidOfSender2",
message: "Hey user 1. How are you?"
}
},
roomid2: {
messageid3: {
fromId: "UidOfSender2",
message: "Hi mom. Are you there?"
},
messageid4: {
fromId: "UidOfSender3",
message: "Hey there kiddo. Sup?"
}
}
}
So in here we have two chat rooms, the first one between user 1 and 2, and the second between users 2 and 3. If you think of your favorite messaging application, you can probably see how the rooms very directly map to the conversations you see.
Also note that you only need to keep the sender ID. The recipient(s) are are simply everyone else who is in this chat room.
That will likely be your next question: how do I know what rooms a user is in. To determine that, you'll want to keep a separate list of room IDs for each user:
userRooms: {
UidOfSender1: {
room1: true,
room2: true
},
UidOfSender2: {
room1: true
},
UidOfSender3: {
room2: true
}
}
So now you can see for each user in what rooms they are a participant. You can probably again see how this maps to the list of conversations when you start your favorite messaging app. To efficiently show such a list, you may want to keep some extra information for each room, such as the timestamp when the last message was posted.
Generating the room IDs is another interesting aspect of this model. In the past I've recommended to use the UIDs of the participants to determine the room ID, since that leads to a consistent, repeatable room ID. For an example if this, see http://stackoverflow.com/questions/33540479/best-way-to-manage-chat-channels-in-firebase.
If you're new to NoSQL database, I recommend reading NoSQL data modeling. If you come from a SQL background, I recommend watching Firebase for SQL developers.
回答2:
var newthing = "\(CurrentChatUserId) & \(otherDude)"
Ref.child("posts").child(newthing).queryOrderedByKey().observe(.childAdded, with: {snapshot in
if let dict = snapshot.value as? [String: AnyObject]
{
let mediaType = dict["MediaType"] as! String
let senderId = dict["senderId"] as! String
let senderName = dict["senderName"] as! String
self.obsereveUsers(id: senderId)
let text = dict["text"] as! String
self.messages.append(JSQMessage(senderId: senderId, displayName: senderName , text: text))
self.collectionView.reloadData()
}
})
You could do something like this, so in the database you have different sections for each conversation and at the start get all past messages, and get new ones when a new one is added.
来源:https://stackoverflow.com/questions/48178492/how-to-observe-all-firebase-database-events-between-two-users-at-concurrent-time