Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I enforce a maximum number of children in a node?

Tags:

firebase

How can I enforce a maximum number of children of a node using a security rule?

/bar/customers/$customer/drinks_ordered

Should not have more than fifteen children.

like image 249
abrkn Avatar asked Feb 17 '13 10:02

abrkn


1 Answers

It might seem like you could use a numeric id for the ordered drinks and then try something like this; it will fail since the ID is a string:

"$customer_id": {
    "drinks_ordered": {
       "$drink_id": {
          ".validate": "$drink_id > 0 && $drink_id < 16" // error
       }
    }
}

Instead, you can use a counter and validate the counter to be 1-15, and then validate the drink ID matches the counter.

"$customer_id": {
    "counter": {
       // counter can only be incremented by 1 each time, must be a number
       // and must be <= 15
       ".validate": "newData.isNumber() && newData.val() > 0 && newData.val() <= 15 && ((!data.exists() && newData.val() === 1) || (newData.val() === data.val()+1))"
    },
    "drinks_ordered": {
       // new record's ID must match the incremented counter
       "$drink_id": {
          // use .val()+'' because $drink_id is a string and Firebase always uses ===!
          ".validate": "root.child('bar/customers/'+$customer_id+'/counter').val()+'' == $drink_id"
       }
    }
}

Naturally, your drinks will look something like this:

 /bar/customers/george_thorogood/counter/3
 /bar/customers/george_thorogood/drinks_ordered/1/burbon
 /bar/customers/george_thorogood/drinks_ordered/2/scotch
 /bar/customers/george_thorogood/drinks_ordered/3/beer

Now before a client could add another drink, they would have to set the counter to 4 (which is the only thing it can be set to) and then add the drink with that same ID.

A little roundabout, but it does do the job : )

like image 143
Kato Avatar answered Nov 10 '22 01:11

Kato