Firebase database rule to only allow one record

Viewed 1491

Is there a Firebase rule so that I can make sure that only one record may exist in a certain table, for example.

enter image description here

When ongoing has a record. It's not possible to add a new one.

count() and length() don't exist for firebase so it seems.

3 Answers

It is possible to do what you want with a security rule.

Because your limit for the maximum number of children is one, you can take advantage of the fact that keys with no children do not exist.

If you use a rule like this:

{
  "rules": {
    "ongoing": {
      "$key": {
        ".read": "auth != null",
        ".write": "auth != null && ((newData.exists() && (!data.parent().exists() || data.exists())) || !newData.exists())"
      }
    }
  }
}

The write will be allowed:

  • if the child is being added and the ongoing key does not exist; or
  • if the child is being updated; or
  • if the child is being removed.

The rule will prevent the addition of another child if one already exists (as the ongoing key will already exist).

You can't express this as a validation rule. What you can do is instead use a Cloud Function to express the logic to accept or reject a change based on existing data. Your client code will need to invoke this function perhaps by a write to a different part of the database, or an HTTPS function.

This may not be exactly what you want but it does provide a solution:

Change your structure from

ongoing
   child_0
      id: "some id"

to

ongoing
    child_count: 1
    child_0
       id: "some id"

and then the rules

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null",
    "ongoing": {
        ".validate": "root.child('ongoing').child('child_count').val() < 1"
    }
  }
}

When you initially create the ongoing node, create it like this

ongoing
   child_count: 0

and then when a node is added, change child_count to 1. From there any more attempts to add or modify the ongoing node will be denied.

Related