2

There are some other (older) questions about this, but since they already are a few years old, I am curious if there have been an update about this. I want to animate a lottery, in which users can buy tickets. Everything is going well, but I want to make sure there are never more than a thousand sold tickets. It has to be server side, and these are my rules:

  "Lottery": {
    ".read": "auth != null",
    ".write": "auth != null",
      "counter": {
        ".validate": "newData.isNumber() && newData.val() > 0 && newData.val() <= 1000 && ((!data.exists() && newData.val() === 1) || (newData.val() === data.val()+1))"
      },
        "tickets":{
          "root.child('Lottery/counter/').val() === someValueYouNeedItToEqual"
        }
  }

I do not know what to write at someValueYouNeedItToEqual. I am concerned about the working of this system. My goal is to write the user's UID to the server, and gets accepted if the value (I can search client side for available spots, the value can be a Int between 0 and 1000) is free. It should be rejected when all spots are taken (1000 children in a node). I hope someone can help me out figuring out the needed validation rules. Thank you.

J. Doe
  • 12,159
  • 9
  • 60
  • 114

2 Answers2

5

There is this guidance already here on SO: Limit number of records that can be written to a path (reference other paths in security rules)

Or you could use Cloud Functions for Firebase to implement a database trigger that both:

  1. Increments/decrements a child count (within in a transaction to be safe) as children come and go.
  2. Checks that child count to make sure the new child is valid for addition, and deletes it (or some other child) if not.
Community
  • 1
  • 1
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
2

You're getting the error because the

"root.child('Lottery/counter/').val()"

expression doesn't return a boolean. It returns the value of whatever is stored at that reference. You can squash the error by trying something like

"root.child('Lottery/counter/').val() === someValueYouNeedItToEqual"
Billy Barry
  • 187
  • 6
  • Thanks :) now I need it to make sure it sets no more than 1000 children. Any ideas how to do this? – J. Doe Apr 13 '17 at 19:59
  • 1
    Unfortunately, there's no native way to get the number of children from firebase's server-side rules. The easiest way I can think of would be to add a "numberOfTickets" reference and increment it every time you add a ticket. Then you just need to write a rule that does something like `"root.child('numberOfTickets').val() < 1000"` – Billy Barry Apr 13 '17 at 20:24