【问题标题】:Firebase Realtime Database Security Rules - How to get into second nodeFirebase 实时数据库安全规则 - 如何进入第二个节点
【发布时间】:2022-01-04 12:43:03
【问题描述】:

我正在为 firebase 实时数据库的安全规则而苦苦挣扎。我的数据库结构如下:

在第一级您有聊天。在第二层有聊天伙伴(与聊天伙伴的用户 ID 连接的字符串)。在第三层,你有消息。最后一级有变量 datetime、userid 和 message。

我的问题是,我怎样才能进入第二个子节点,例如检查 auth.uid 是否在串联字符串中。我的想法是给用户读取权限,如果用户 ID 在聊天伙伴字符串中,以确保只有聊天伙伴可以读取他们的消息。或者这是一个思维错误? 我尝试了很多东西,但没有成功:

"Chats":{
   ".read": "root.child('Chats').val().contains('auth.uid')"    
 }

#更新

{
 "rules": {
   "Chats": {
     "$chatid": {
      ".read": "$chatid.contains(auth.uid)",
      ".write": "auth != null"
      }
   },
   "Suchencards": {
      ".read": "true",
            ".write": "auth != null"
   },
   "UserData": {
     "$uid": {
      ".read": "$uid === auth.uid",
            ".write": "$uid === auth.uid"
     }
   }
 }
}

我正在使用 firebase 控制台上的 Playground 来检查我得到的是真还是假,但是在这种情况下我得到的是假。

#更新 2

Screen1

Screen2

【问题讨论】:

  • 如果您使用规则游乐场进行测试,请显示所有相关值可见的游乐场屏幕截图。
  • 添加了截图。

标签: firebase firebase-realtime-database firebase-security


【解决方案1】:

如果您知道数据的确切路径,您只能访问规则中的数据,因此您将无法访问 /Chats 上规则中的所有聊天。尝试这样做通常意味着您尝试在错误的级别上定义规则。

例如,如果您希望允许用户读取 Chats 的特定子级,则需要在该级别定义规则:

"Chats":{
  "$chatid": {
    ".read": "$chatid.contains(auth.uid)"
  }
}

虽然上述方法适用于访问特定房间,但您将无法使用它来查询用户有权访问的所有聊天室(因为 Firebase 查询不支持“包含”操作)。请查看我的答案中的 userChatrooms 节点,以获得更好的模型来跟踪用户的聊天室:Best way to manage Chat channels in Firebase

【讨论】:

  • 谢谢弗兰克!尝试使用通配符解决方案 $chatid.contains() 提供的代码块。我将 auth.uid 放入包含以及整个串联字符串中。两者都给了我一个错误,而不是一个真实的,尽管连接的字符串在数据库中。
  • 您能否更新您的问题以显示更新后的规则以及重现问题的最少代码(因为规则本身不会做任何事情)?
  • 好的,刚刚编辑/更新了我的帖子。
  • 您正在尝试读取这些屏幕截图中的/Chats/chatid,这意味着$chatid"chatid",并且不包含您使用的UID。要使其工作,请读取包含 UID 的路径。
  • 谢谢弗兰克。它在读取正确路径时工作正常,但是在设备上尝试时出现问题。会检查的。