如何访问 newData 服务器变量的键?

Tom*_* C. 2 firebase firebase-security firebase-realtime-database

(如果需要进一步澄清,请参阅修订后的问题和评论)

鉴于此数据结构

{
  "-KWz2G9JKtwqt5Kn-pL7":true
}
Run Code Online (Sandbox Code Playgroud)

当我尝试验证 newData 时,如何从 Firebase 验证规则中访问第一个值(“-KWz2G9JKtwqt5Kn-pL7”)?

请在下面找到我的原始问题。

背景

在线示例表明,连接 Firebase 实体的最佳方式是使用索引,其中收集与另一个实体节点内的一个实体相关的 id。

例如;

"groups":{ 
...
  "members":{
   "userid-1":true, 
   "userid-2":true
   }
 }
Run Code Online (Sandbox Code Playgroud)

我想使用以下数据结构将索引发布到另一个实体(队列/队列/任务)下的节点,并使用以下描述的规则集验证该数据结构:

{
  "-KWz2G9JKtwqt5Kn-pL7":true
}
Run Code Online (Sandbox Code Playgroud)

数据结构是对我想要与单独实体的节点关联的任务实体 (/tasks/task/tid) 的引用。

我计划将这些值放入字典并通过 setValue 添加它。当我这样做时,Firebase 应该应用验证规则。我想验证标识符是否存在于数据库中的其他地方。

我的索引看起来像这样 (其中标识符与存储在另一个位置的一组任务 ID 相关)

"queues":{
....
   "K24395498054-p23"{
     "tasks": {
        "-KWz2G9JKtwqt5Kn-pL7":true,
        "-KWjewrkstwqt7Ln-pL3":true,
        "-KWjewgqjdsllfsn-pL5":true
      }
    }
 }
Run Code Online (Sandbox Code Playgroud)

但是我不清楚如何在规则中解压缩 newData 服务器变量的第一个值,在这种情况下,我没有子标识符。

我没有发送单一值,而是向 Firebase 发送字典。

在这种情况下 newData 应该等于

{
  "-KWz2G9JKtwqt5Kn-pL7":true
}
Run Code Online (Sandbox Code Playgroud)

Nota Bene - 一个有趣的旁注;我正在尝试创建索引,但正在阅读 setValue 文档。它指出该值将被覆盖。那么如何在不覆盖现有值的情况下保存字典?

规则

{
  "rules": {
    ".read": "auth != null",
    "queues": {
      ".write":"auth.provider != 'anonymous'",
      "$qid": {
       "members" : {
         //unsure how to access the first value of the newData object without it having a label but the following shows what I am trying to accomplish
         ".validate":"root.child('tasks').hasChild('-KWz2G9JKtwqt5Kn-pL7')",
         }   
       }
     }
    }
  }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我确认添加的 newData 是已作为任务存在的有效唯一标识符。在此规则中,任务将与队列实体相关联。

如果有帮助,请在下面查看我的实体地图: 实体映射

或者

如何创建类似于我在您的示例中在线看到的索引?:

表示我可能与用户关联的一组组....

"user_0" : {
....
    "groups" : { 
       "group_id0":true,
       "group_id1":true,
       "group_id2":true
    }
}
Run Code Online (Sandbox Code Playgroud)

之后,我如何验证 a 是否group_id#确实存在于我的组节点下的其他地方?

如果我能得到那个答案,我也许可以根据我的需要进行推断。

更新

根据接受的答案,我已经能够成功地应用以下规则来实现预期的结果:

{
  "rules": {
    ".read":  "false",
    ".write": "(auth.provider != 'anonymous') && (auth != null)",

      "presence": {
        ".read": "(auth.provider != 'anonymous') && (auth != null)",
            ".write": "(auth.provider != 'anonymous') && (auth != null)",
      },

      "queues": { 
        ".read":"(auth != null)",
        ".write": "(auth.provider != 'anonymous') && (auth != null)",
            "$qid": {
                "tasks": {
                "$taskid": {
                    ".validate": "root.child('tasks').child($taskid).exists()"
                }
                }
            }
        },

      "tasks": {
         ".read": "(auth != null)",
          ".write": "(auth.provider != 'anonymous') && (auth != null)",
        "$taskid":{
          "queues":{
              "$qid": {
              ".validate":"root.child('queues').child($qid).exists()"              
              }
            }
          }
        },

       "users": {
          ".read": "(auth != null)",
          ".write": "(auth != null)",
            "$userid":{
            "groups":{
              "$gid": {
              ".validate":"root.child('groups').child($gid).exists()"              
              }
            },
            "roles":{
              "$rid": {
              ".validate":"root.child('roles').child($rid).exists()"              
              }
            },
            "metadata":{
             ".read": "(auth != null)",
             ".write": "(auth.provider != 'anonymous') && (auth != null)",
            }
          }
        },
        "roles": {
          ".read": "(auth != null)",
          ".write": "(auth != null)",
        },
       "groups":{
          ".read": "(auth != null)",
          ".write": "(auth != null)",
            },  
    } //eof-rules  
}
Run Code Online (Sandbox Code Playgroud)

car*_*ant 5

您需要向规则添加另一个级别,以便您可以$为任务 ID使用变量:

{
  "rules": {
    ".read": "auth != null",
    "queues": {
      ".write": "auth.provider != 'anonymous'",
      "$qid": {
        "members": {
          "$taskid": {
            ".validate": "root.child('tasks').hasChild($taskid)"
          }
        }   
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用setupdate将任务 ID 添加到索引:

firebase
  .database()
  .ref("queues/K24395498054-p23/members/-KWz2G9JKtwqt5Kn-pL7")
  .set(true);

firebase
  .database()
  .ref("queues/K24395498054-p23/members")
  .update({ "-KWz2G9JKtwqt5Kn-pL7": true });
Run Code Online (Sandbox Code Playgroud)