MandM
MandM

Reputation: 3383

Firebase security rules ensure children conditional

I'm using the Firebase Bolt Compiler to build my security rules and I've come across the following scenario:

The following is my attempt, using Bolt, to construct these rules:

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
}

Here is the following rules.json:

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

It can be seen that the .validate rule enforces all children to be present in data. So, how can I ensure that, based on my conditions, the .validate rules for both data and each of its children are correct?

Upvotes: 1

Views: 1027

Answers (1)

mckoss
mckoss

Reputation: 7014

Since your type can be Null, you must extend Number | Null like so:

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;
}

Which results in the following JSON rules file:

{
  "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"
    }
  }
}

Upvotes: 3

Related Questions