如何在并发时观察两个用户之间的所有firebase数据库事件?

首先,如果您对此提交有更好的标题或实际问题的建议,请随时编辑。 我被问到如何成功地提出这个问题。

所以我已经为swift做了几个Firebase聊天(iMessage / Facebook聊天)教程。 我知道如何发送消息 –

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 ... 

而且我知道如何检索它们 –

  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 let message = values["Message"] let from = values["fromID"] let post = ChatMessages() post.aMessage = message! post.Interested = from! self.messagesArray.append(post) self.tableView.reloadData() }) 

但是,我很难完成逻辑。 我不明白这两个单独的事件是如何组合成一个相同的最终结果 – 而不是两个不同的事务。 让我看看我是否可以进一步解释……

我发了一条消息。 然后我以另一个用户的身份收到此消息。 但我不明白如何同时下载同时引用/来自数据的数据。 除非我看起来忽略了一些细节,否则事件的单个或复数观察不适用于一个用户? 或者我在这里误解了一些概念?

帮助这个最终的概念将是太棒了。 谢谢。

您现在有一个聊天消息列表,这与您在关系数据库中对此进行建模的方式非常相似。 但Firebase是NoSQL数据库,因此您有更好的聊天建模选项。

最常见的解决方案是将聊天室建模到您的数据库中。 因此,如果两个用户正在聊天,则这两个用户之间的消息将位于“房间节点”中。 如果其他两个用户也在聊天,他们的消息将在一个单独的房间里。 此数据模型如下所示:

 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?" } } } 

所以在这里我们有两个聊天室,第一个在用户1和2之间,第二个在用户2和3之间。如果您想到自己喜欢的消息应用程序,您可以看到房间如何直接映射到您的对话看到。

另请注意,您只需要保留发件人ID。 收件人就是这个聊天室里的所有其他人。

这可能是您的下一个问题:我如何知道用户所在的房间。要确定这一点,您需要为每个用户保留单独的房间ID列表:

 userRooms: { UidOfSender1: { room1: true, room2: true }, UidOfSender2: { room1: true }, UidOfSender3: { room2: true } } 

所以现在你可以看到每个用户在他们参与的房间里。 当您启动collections的消息传递应用程序时,您可能会再次看到它如何映射到对话列表。 要有效地显示此类列表,您可能需要为每个房间保留一些额外信息,例如上次发布消息时的时间戳。

生成房间ID是该模型的另一个有趣方面。 在过去,我建议使用参与者的UID来确定房间ID,因为这会产生一致的,可重复的房间ID。 有关此示例,请参阅http://stackoverflow.com/questions/33540479/best-way-to-manage-chat-c​​hannels-in-firebase 。

如果您是NoSQL数据库的新手,我建议您阅读NoSQL数据建模 。 如果您来自SQL背景,我建议您为SQL开发人员观看Firebase 。

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

你可以这样做,所以在数据库中,每个对话都有不同的部分,并且在开始时获取所有过去的消息,并在添加新消息时获得新的消息。