Use Predefined Variables
There are a number of helpful, predefined variables that can be accessed inside a security rule definition. Here is a brief summary of each:
Variable Description nowThe current time in milliseconds since Linux epoch. This works particularly well for validating timestamps created with the SDK's Webcom.ServerValue.TIMESTAMP. rootA RuleDataSnapshot representing the root path in Webcom as it exists before the attempted operation. newDataA RuleDataSnapshot representing the data as it would exist after the attempted operation. It includes the new data being written and existing data. dataA RuleDataSnapshot representing the data as it existed before the attempted operation. $variablesA wildcard path used to represent ids and dynamic child keys. authRepresents an authenticated user's token payload.
These variables can be used anywhere in your Security and [[service]] Rules. For example, the security rules below ensure that data written to the /foo/ node must be a string less than 100 characters:
{
"rules": {
"foo": {
// /foo is readable by the world
".read": true,
// /foo is writable by the world
".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
Your Security and [[service]] Rules should follow the structure of the data you have stored in your [[service]]. For example, say you are keeping track of a list of messages and that your data looks like this:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"date": 1405704395231
},
...
}
}Your rules should be structured in a similar manner. We can make use of $ variables in rules which represent dynamic child keys. In addition, we can use .validate rules to ensure our data is properly structured. For example, the $message variable below represents each of the /messages/ node's children:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
}
}
}
}