【问题标题】:How to observe all firebase database events between two users at concurrent time?如何同时观察两个用户之间的所有firebase数据库事件?
【发布时间】:2018-01-10 09:32:41
【问题描述】:

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

所以我已经快速浏览了几个 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<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()
   })

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

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

对这个最终概念的帮助会很棒。谢谢。

【问题讨论】:

  • 嘿,我很困惑。你的问题是什么。是否使消息出现在两个设备上?
  • 我不明白如何编码发送和接收的消息出现在同一个数据集中。
  • 在数据库中还是在应用程序中?
  • AKA,我知道如何分别下载/查看发送和接收的新消息,但我不知道如何将来自两个不同用户的这两个操作组合到一个数组中 - 我说轻轻“阵列”。
  • 从数据库中的应用程序中。

标签: ios swift firebase firebase-realtime-database chat


【解决方案1】:

您现在有一个聊天消息列表,这与您在关系数据库中建模的方式非常相似。但 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
  }
}

所以现在您可以查看每个用户在哪些房间中是参与者。当您启动您最喜欢的消息应用程序时,您可能会再次看到它如何映射到对话列表。为了有效地显示这样的列表,您可能希望为每个房间保留一些额外的信息,例如最后一条消息发布时的时间戳。

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

如果您是 NoSQL 数据库的新手,我建议您阅读 NoSQL data modeling。如果你有 SQL 背景,推荐看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()
    
           }
    })
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-26
      • 2011-10-29
      • 2022-01-19
      • 2021-10-17
      相关资源
      最近更新 更多