Javascript 限制集合内的用户访问firebase数据库

Javascript 限制集合内的用户访问firebase数据库,javascript,firebase,firebase-realtime-database,firebase-security,ionic3,Javascript,Firebase,Firebase Realtime Database,Firebase Security,Ionic3,不久前,我编写了一个简单的聊天应用程序来帮助我学习node和socket.io,最近我一直在研究firebase作为一个应用程序/网站的平台,我遇到了一个无法解决的有趣问题。在应用程序中会有一个聊天应用程序,会有频道和所有的好东西,困难的是会有私人聊天,两个用户可以私下聊天。计划是将聊天存储在firebase数据库中。现在,我可以根据用户是否经过身份验证来轻松限制对firebase数据库的访问,甚至可以将用户配置文件的访问限制为经过身份验证的用户和拥有该配置文件的用户,但我正在尝试找出如何将访问

不久前,我编写了一个简单的聊天应用程序来帮助我学习node和socket.io,最近我一直在研究firebase作为一个应用程序/网站的平台,我遇到了一个无法解决的有趣问题。在应用程序中会有一个聊天应用程序,会有频道和所有的好东西,困难的是会有私人聊天,两个用户可以私下聊天。计划是将聊天存储在firebase数据库中。现在,我可以根据用户是否经过身份验证来轻松限制对firebase数据库的访问,甚至可以将用户配置文件的访问限制为经过身份验证的用户和拥有该配置文件的用户,但我正在尝试找出如何将访问“聊天”数据库的“私人聊天”子项的权限限制为仅限于对话中的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"
    }
  }
}
然后,我会将访问子对象(私有聊天id)的权限限制为仅“users”数组中的用户。这样,没有人可以读或写那个特定的聊天,除非他们在那个特定的聊天。我只是不知道该怎么做。 我知道你可以做这样的事情

.read:“auth!==null&&auth.uid=$uid”

但我不认为这是适用的,因为它限制了uid所有者的使用,并且当我在“chat”中添加一个孩子以开始用户之间的私人聊天时,uid将自动生成

这样的事情是可能的,还是有更好的方法来组织数据,只允许对话中的两个用户轻松访问?
我试图避免让node.js服务器坐在那里只是验证用户是否在聊天,这似乎是一种毫无意义的开销,因为您可以列出数据库并直接从数据库处理auth。我非常乐意提供我所拥有的代码示例,尽管我不知道它们是否相关。提前感谢您的帮助。

您的第一个问题是将用户存储在阵列中。数组是可以具有重复值的有序集合。在您的场景中,您不需要重复的值,而且很可能顺序并不重要。在这种情况下,您应该使用数据结构,该数据结构在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>: { ... }
聊天
房间
克雷登:。。。。
.... 房间的其他元数据
客房用户
用户_id1:true
用户_id2:true
房间信息
: { ... }
: { ... }
: { ... }

您的第一个问题是将用户存储在一个数组中。数组是可以具有重复值的有序集合。在您的场景中,您不需要重复的值,而且很可能顺序并不重要。在这种情况下,您应该使用数据结构,该数据结构在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>: { ... }
聊天
房间
克雷登:。。。。
.... 房间的其他元数据
客房用户
用户_id1:true
用户_id2:true
房间信息
: { ... }
: { ... }
: { ... }

纯粹的天才。非常感谢你。我真的很高兴你也注意到了数据建模,我不太确定我的方法是否正确。我来自一个非常强大的MySQL/PHP背景,所以我仍然掌握着这种数据建模的诀窍。非常感谢你!不客气。如果您是NoSQL的新手,我建议您阅读。如果你有SQL背景,也可以看我们的系列节目。纯粹的天才。非常感谢你。我真的很高兴你也注意到了数据建模,我不太确定我的方法是否正确。我来自一个非常强大的MySQL/PHP背景,所以我仍然掌握着这种数据建模的诀窍。非常感谢你!不客气。如果您是NoSQL的新手,我建议您阅读。如果您来自SQL背景,也请观看我们的系列节目。