Firebase安全规则确保子项有条件

时间:2016-01-08 21:19:51

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

我正在使用Firebase Bolt Compiler来构建我的安全规则,我遇到了以下情况:

  • 我想要以下列形式发布到Firebase的一些嵌套数据:

    data: {
      a: //Number, must always be present
      b: //Number, conditionally present (condition B)
      c: //Number, conditionally present (condition C)
    }
    
  • 条件B和C基于一段数据,其他地方是Firebase,如果符合,我希望包含值,但如果不满足,我希望值为null

    root.condition >= 5  //condition B
    root.condition >= 10 //condition C
    

以下是我使用Bolt构建这些规则的尝试:

type ConditionB extends Number {
  validate() = root.condition >= 5 ? this != null : this == null;
} 

type ConditionC extends Number {
  validate() = root.condition >= 10 ? this != null : this == null;
}

type Data {
  a: Number,
  b: ConditionB,
  c: ContitionC
}

path /data is Data {
  read()  = true,
  write() = true
}

以下是rules.json:

"rules": {
  "data": {
    ".validate": "newData.hasChildren(['a', 'b', 'c']),
    ...
  }
}

可以看出,.validate规则强制所有子项都出现在data中。那么,我如何根据我的条件确保.validate data及其每个孩子的second规则都正确无误?

1 个答案:

答案 0 :(得分:3)

由于您的类型可以为Null,因此必须扩展Number |像这样空:

type ConditionB extends Number | Null {
  validate() = root.condition >= 5 ? this != null : this == null;
}

type ConditionC extends Number | Null {
  validate() = root.condition >= 10 ? this != null : this == null;
}

type Data {
  a: Number,
  b: ConditionB,
  c: ConditionC
}

path /data is Data {
  read() = true;
  write() = true;
}

这导致以下JSON规则文件:

{
  "rules": {
    "data": {
      ".validate": "newData.hasChildren(['a'])",
      "a": {
        ".validate": "newData.isNumber()"
      },
      "b": {
        ".validate": "(newData.isNumber() || newData.val() == null) && (newData.parent().parent().child('condition').val() >= 5 ? newData.val() != null : newData.val() == null)"
      },
      "c": {
        ".validate": "(newData.isNumber() || newData.val() == null) && (newData.parent().parent().child('condition').val() >= 10 ? newData.val() != null : newData.val() == null)"
      },
      "$other": {
        ".validate": "false"
      },
      ".read": "true",
      ".write": "true"
    }
  }
}