Skip to content Skip to sidebar Skip to footer

Firebase Data Cap On Children

Is there any way to set a data cap on Firebase children? E.g.,... { Customer1: {}, Customer2: {}, Customer3: {} } For my particular example, depending on a customer's

Solution 1:

After some trial and error i found out it is actually possible to have a cap on data within the firebase security rules. But only to a certain extend!

The limiting factor is that you can only check the value of a primitive type (string, number or bool). When a node has children you would have to check the value of each of that children, this implies you know what data you can expect.

Below is an example of the security rules needed to accomplish this. The rules are only for a primitive type or a node with a maximum of 3 (specified) primitive children.

"rules": {
  ".read": true,
  ".write": true,
  "$key":{
    //validate that the data has no children
    ".validate":"(!newData.hasChildren() && 
    //and validate if it is a string within a certain length
    (newData.isString() && newData.val().length < 10) || 
    //or validate if it is a number within a certain range
    (newData.isNumber() && (newData.val() < 10 && newData.val() > -10)) || 
    //or validate if it is a bool
    newData.isBoolean()) || 
    //Or rince and repeat for all possible child nodes
    newData.hasChildren()",
    "childA":{
      ".validate":"(!newData.hasChildren() && 
      (newData.isString() && newData.val().length < 10) || 
      (newData.isNumber() && (newData.val() < 10 && newData.val() > -10)) || 
      newData.isBoolean())"
    },
    "childB":{
      ".validate":"(!newData.hasChildren() && 
      (newData.isString() && newData.val().length < 10) || 
      (newData.isNumber() && (newData.val() < 10 && newData.val() > -10)) || 
      newData.isBoolean())"
    },
    "childC":{
      ".validate":"(!newData.hasChildren() && 
      (newData.isString() && newData.val().length < 10) || 
      (newData.isNumber() && (newData.val() < 10 && newData.val() > -10)) || 
      newData.isBoolean())"
    },
    //dismiss all child nodes you don't want
    "$other": {".validate": false}
  }
}

Some of the downsides about this sollution are:

  1. You have to know what data you can expect (and update your rules each time this changes)
  2. The rules will get exponentially larger the more child nodes you can have
  3. You can't really have a "total" cap on a node but only on the primitives that make up a node. For example (childA + childB + childC) is smaller then X is not possible.
  4. You can't have a dynamic cap. But you could say locationFree has a cap of 10 and locationPremium has a cap of 100. But unfortunatly this would double the amount of rules needed and users will have different write locations depending on their cap.

Solution 2:

This is one of those requirements that you can't implement in the client-side application as the users will be able to bypass them if you do.

Instead you should implement this server-side, which leaves:

  • implement it in security rules
  • implement it in server-side code

There is no operator built-in Firebase Security Rules that gives the size of a node. You can determine the length of a string, but that's a bit little to go on.

So your best bet is to use server-side process, which is: a process that you control, which doesn't run on the client's device. With that server-side process you can calculate the node size in any way you see fit.

The process then writes the node size back into Firebase into a secured location (that only the process can write). The security rules can then check against this location and reject writes if the node is larger than the quota.


Post a Comment for "Firebase Data Cap On Children"