【问题标题】:How to access the key of the newData server variable?如何访问 newData 服务器变量的键?
【发布时间】:2017-04-03 16:28:32
【问题描述】:

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

给定这个数据结构

{
  "-KWz2G9JKtwqt5Kn-pL7":true
}

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

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

背景

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

例如;

"groups":{ 
...
  "members":{
   "userid-1":true, 
   "userid-2":true
   }
 }

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

{
  "-KWz2G9JKtwqt5Kn-pL7":true
}

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

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

我的索引将如下所示 (其中标识符与存储在另一个位置的一组任务 ID 相关)

"queues":{
....
   "K24395498054-p23"{
     "tasks": {
        "-KWz2G9JKtwqt5Kn-pL7":true,
        "-KWjewrkstwqt7Ln-pL3":true,
        "-KWjewgqjdsllfsn-pL5":true
      }
    }
 }

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

我不是发送一个奇异值,而是向 Firebase 发送一个字典。

newData 在这种情况下应该等于

{
  "-KWz2G9JKtwqt5Kn-pL7":true
}

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')",
         }   
       }
     }
    }
  }

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

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

或者

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

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

"user_0" : {
....
    "groups" : { 
       "group_id0":true,
       "group_id1":true,
       "group_id2":true
    }
}

之后,我如何验证 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  
}

【问题讨论】:

  • 我已经澄清了这个问题。如果不清楚,请发表评论。

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


【解决方案1】:

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

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

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

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

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

【讨论】:

  • +1 用于创建索引的示例。看到规则旁边的内容触发了一个标志,我已将其应用于整个 JSON 树。我已经发布了我的规则,以便此问答可以帮助下一个人。
猜你喜欢
  • 1970-01-01
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
  • 2018-07-26
  • 1970-01-01
相关资源
最近更新 更多