Swift Firebase数据库中的多用户聊天室数据结构

Swift Firebase数据库中的多用户聊天室数据结构,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,我很难弄清楚如何正确构建多用户聊天室FirebaseDatabase体系结构 基本上,该应用程序支持用户之间的私人消息(可以是两个用户之间或多个用户之间)。如果只在两个用户之间,数据结构就非常简单 我试图降低成本(我不希望当前登录的用户正在与某人聊天,而观察者正在获取与此特定聊天无关的所有消息),并正确地构造数据。如果它仅在2个用户之间,我总是可以在当前用户ID下添加recepient,并仅查询该节点。但是对于多个用户(甚至不知道有多少),我需要依赖聊天室Id,但我很难做到这一点 因此,这里的想

我很难弄清楚如何正确构建多用户聊天室
FirebaseDatabase
体系结构

基本上,该应用程序支持用户之间的私人消息(可以是两个用户之间或多个用户之间)。如果只在两个用户之间,数据结构就非常简单

我试图降低成本(我不希望当前登录的用户正在与某人聊天,而观察者正在获取与此特定聊天无关的所有消息),并正确地构造数据。如果它仅在2个用户之间,我总是可以在当前用户ID下添加recepient,并仅查询该节点。但是对于多个用户(甚至不知道有多少),我需要依赖聊天室Id,但我很难做到这一点

因此,这里的想法,让我们假设用户选择另一个开始聊天。我在想这样的事情:


我面临的问题是维护
chatId
。每次用户要发送新消息时,我如何根据
chatId
检查是否已经有与相同接收者的聊天。这是让我困惑的部分。我已经在这上面呆了好几天了,我想不出一个正确的方法来维护
chatId
并正确地查询它。欢迎提供任何帮助。

如果我理解这个问题,该应用程序有多个用户,这些用户可能有1-1或1-many聊天记录,您希望避免用户获得他们不参与的聊天记录

让我们从一个用户节点开始

users
  uid_0
    name: "Bill"
    chats:
      chat_id_0: true
      chat_id_9: true
  uid_1
    name: "Jesse"
    chats:
      chat_id_0: true
      chat_id_6: true
  .
  .
  .
然后是一个简化的聊天节点

chats
   chat_id_0:
     uid_0: "Hey there, Jesse"
     uid_1: "Sup Bill?"
   chat_id_6:
     uid_0: "This is Bill, anyone around?"
   chat_id_9:
     uid_1: "Look ma, no hands"
     uid_7: "Impressive"
在上面,当用户开始聊天时,chat_id_x是用.childByAutoId创建的

当Bill登录时(uid_0),读取他的聊天节点,然后向该节点中列出的聊天添加观察者。在本例中,Bill是chat_id_0和chat_id_9的一部分。对属于0和6的Jesse执行相同的过程

Bill和Jesse正在chat_id_0中聊天,Bill正在等待任何观看chat_id_6的用户的回复,Jesse正在chat_id_9中与uid_7对话

从那时起,任何时候都有一个事件(例如,当一条新消息被添加到聊天中时,添加了一个childAdded),只有那些观察该聊天的用户(“订阅”)才会收到一个事件

显然,每个聊天节点中都会包含更多的细节(时间戳等)

如何检查是否已经与同一个最近者(或 (最新版本)基于chatId

有几种方法可以解决这个问题

一个是,当一个观察者被添加到您所属的每个聊天中(.childAdded)时,该聊天节点中的每个子节点都将返回到您的应用程序。这有两个好处-一是用现有的聊天信息填充UI,二是。。。然后你就会知道谁参与了那次聊天。将这些UID与聊天id放在一个数组中,在向此人发送聊天之前,查看它们是否作为现有聊天存在于数组中

第二个选项是查询用户uid出现在其中的所有聊天记录(使用.observeSingleEvent进行查询)。这将返回他们所属的所有聊天节点,然后有他们聊天的其他人的uid以及聊天id

另一个选项是,在创建聊天时,/chat\u id\u 0,添加一个名为/who\u dat的子节点,该节点保存被邀请参加聊天的人的列表

chats
  chat_id_0
     who_dat
        uid_0: true
        uid_1: true
        uid_2: true
     messages:
        uid_0: "Hey there, Jesse"
        uid_1: "Sup Bill?"

在本例中,uid_2也被添加到聊天室id_0中,但尚未收到他们的消息。

我通常建议使用基于参与者uid的“房间id”。这意味着,对于相同的参与者,您将始终获得相同的房间ID。关于这方面的一个简单示例,请参见@FrankvanPuffelen,如果您有30名参与者怎么办?
uid
会不会太长?我不确定
Firebase
中的
id
长度是否有最大限制。比如,假设您的典型用户
uid
是这么长的
5jikveb2fmdmd626iyjrykdkf2
。现在,如果我们得到所有的用户
uid
s,那么它是否会被允许/接受为
roomId
值,因为它将非常长?在这种情况下,您可以对连接的uid进行哈希处理。碰撞的机会对我来说似乎很小。或者,您可以为每个用户创建单独的房间ID查找,如图所示:和!谢谢你的详细解释,我觉得我还有更多的问题要问,但我会在我达到这一点时分别发帖。再次感谢你!