将对 firebase 数据库的访问限制为一组中的用户

restricting access to firebase database to users within a set

前一段时间我写了一个简单的聊天应用程序来帮助我学习节点和 socket.io,我最近一直在研究 firebase 作为 app/website 的平台,我 [=29] =] 变成一个我无法解决的有趣问题。在应用程序中会有一个聊天应用程序,会有频道和所有好东西,困难的部分是会有私人聊天,2 个用户可以私下交谈。计划是将聊天存储在 firebase 数据库中。现在我可以根据用户是否经过身份验证轻松限制对 firebase 数据库的访问,甚至可以将用户配置文件访问权限限制为经过身份验证的用户和拥有该配置文件的用户,但我想弄清楚如何限制对 "private chat" children 的 "chat" 数据库,仅提供给该对话中的 2 个用户。 我认为数据库看起来像这样...

{
  "chat": {
    "channels": ['topics', 'current', 'blah', 'blah', 'blah'],
    "{PRIVATE_CHAT_UID_GOES_HERE}": {
      "users": ["{USER_ID_1}", "{USER_ID_2}"],
      "messages": [{"from": "{USER_ID}", "message": "Hi there"},{...}]
      "createdOn": "DATE GOES HERE"
    },
    "{PRIVATE_CHAT_UID_GOES_HERE}": {
      "users": ["{USER_ID}", "{USER_ID}"],
      "messages": [{...}, {...}],
      "createdOn": "DATE GOES HERE"
    }
  }
}

然后我会将对 child(私人聊天 ID)的访问限制为仅 "users" 数组中的用户。这样一来,除非他们在那个特定的聊天中,否则没有人可以读取或写入该特定的聊天。我只是不知道该怎么做。 我知道你可以做

".read": "auth !== null && auth.uid = $uid"

但我认为这不适用,因为它限制了 uid 所有者的使用,并且当我将 child 添加到 "chat" 开始时,uid 会自动生成用户之间的私人聊天。

这样的事情是否可能,或者是否有更好的方法来构建数据,以便轻松地将访问权限限制为仅参与对话的 2 个用户? 我试图避免让 node.js 服务器闲置只是验证用户是否在聊天,这似乎是毫无意义的开销,当您可以列出数据库并直接从数据库处理身份验证时。我非常乐意提供我所拥有的代码示例,尽管我不知道它们是否相关。预先感谢您的帮助。

您的第一个问题是您将用户存储在一个数组中。数组是可以具有重复值的有序集合。在您的场景中,您不想要重复值,而且顺序很可能无关紧要。在这种情况下,您应该使用 set 数据结构,它在 Firebase 中被建模为:

"users": {
  "{USER_ID_1}": true,
  "{USER_ID_2}": true
}

现在您可以通过以下方式限制聊天室成员的读取权限:

{
  "rules": {
    "chat": {
      "$roomid": {
        ".read": "data.child('members').child(auth.uid).exists()
      }
    }
  }
}

小心在同一个节点中混合使用不同的数据类型。通常最好将每个实体保留在其自己的顶级节点中,通过键将不同类型相关联。例如,我会将房间的消息、成员和其他元数据分开:

chat
  rooms
    <roomid1>
      createdOn: ....
      .... other metadata for the room
  roomUsers
    <roomid1>
      user_id1: true
      user_id2: true
  roomMessages
    <roomid1>
      <message1>: { ... }
      <message2>: { ... }
      <message3>: { ... }