Tutorial: Writing rules

Serverless DatabaseSecurity Rules Writing rules

Use Predefined Variables

When writing a security rule, you can use a number of helpful, predefined JavaScript variables:

Variable Description
now The current time in milliseconds since Unix Epoch. This works particularly well for validating timestamps created with server timestamps.
root A RuleDataSnapshot representing the root path of the Webcom application database, as it exists before the attempted operation.
newData A RuleDataSnapshot representing the data as it would exist after the attempted write operation at the specified path. It merges both the new data being written and the already existing data.
data A RuleDataSnapshot representing the data as it existed before the attempted (write or read) operation at the specified path.
$level A wildcard path level used to represent dynamic child keys (see below).
auth The authentication payload of the currently authenticated user or null if no user is authenticated (see the “Using rules to control authentication”).

These variables can be used anywhere in your security rules. For example, the following security rules ensure that data written to the /foo/ node must be a string less than 100 characters:

{
  "rules": {
    "foo": {
      // /foo is readable by anyone
      ".read": true,
      // /foo is writable by anyone
      ".write": true,
      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

Make Your Rules Dynamic

The security rules must be defined in a hierarchy of levels that follows the structure of the data nodes stored in the Webcom database. For example, say you are keeping track of a list of messages. Your data could look like:

{
  "messages": {
    "m-001": {
      "content": "Hello",
      "timestamp": 1405704370369
    },
    "m-002": {
      "content": "Goodbye",
      "timestamp": 1405704395231
    },
    ...
  }
}

Your rules should be structured in a similar manner. You can use $ prefixed levels to refer to some levels that you can't know the exact name in advance (like for example the message identifiers). You are then provided with a JavaScript variable with the same ($-prefixed) name to get this name within the security rule.

To illustrate, take a look at the following validation rule (pay attention to the $id level and its corresponding JavaScript variable):

{
  "rules": {
    "messages": {
      "$id": {
        // only messages from the last ten minutes can be read by anyone
        ".read": "data.child('timestamp').val() > (now - 600000)",
        // new messages must have their path starting with "m", 2 children and their content attribute of type string
        ".validate": "$id[0]==='m' && newData.hasChildren(['content','timestamp']) && newData.child('content').isString()"
      }
    }
  }
}