5 minute quickstart

Security & Rules Quickstart

Firebase provides a flexible, expression-based rules language with JavaScript-like syntax to easily define how your data should be structured and when your data can be read from and written to. Combined with our login service which allows for easy authentication, you can define who has access to what data and keep all of your user's personal information secure. The Security and Firebase Rules live on the Firebase servers and are automatically enforced at all times.

Understand the Default Security and Firebase Rules

Security and Firebase Rules are used to determine who has read and write access to your database as well to ensure the structure of that data. They are found in the Security tab of your App Dashboard. They come in three flavors: .write, .read, and .validate. Here is a quick summary of their purpose:

Rule Type Description
.read Describes if and when data is allowed to be read by users.
.write Describes if and when data is allowed to be written.
.validate Defines what a correctly formatted value will look like, whether it has child attributes, and the data type.

Security and Firebase Rules have a JavaScript-like syntax which makes them easy to work with. By default, your app has rules which grants every request full read and write permissions to your database:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Security and Firebase Rules live on the Firebase servers and are enforced at all times. Every read and write request will only be completed if your rules allow it. With the default rules above, all requests will be permitted.

Security Behind the Scenes

Firebase handles many other security details for you. Specifically, we use strong 2048 bit keys for our SSL certificates, sign authentication tokens with SHA256 HMAC signatures, and use BCrypt for password storage.

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
now The current time in milliseconds since Linux epoch. This works particularly well for validating timestamps created with the SDK's Firebase.ServerValue.TIMESTAMP.
root A RuleDataSnapshot representing the root path in the Firebase database as it exists before the attempted operation.
newData A RuleDataSnapshot representing the data as it would exist after the attempted operation. It includes the new data being written and existing data.
data A RuleDataSnapshot representing the data as it existed before the attempted operation.
$ variables A wildcard path used to represent ids and dynamic child keys.
auth Represents an authenticated user's token payload.

These variables can be used anywhere in your Security and Firebase 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 Firebase Rules should follow the structure of the data you have stored in your database. 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",
      "timestamp": 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()"
      }
    }
  }
}

Integrate Authentication Rules

Firebase gives you full control over user authentication. Login providers are server-side components that authenticate your users. Choose a built-in login provider for a common authentication use case, or build your own custom login provider to address special login needs.

No matter how you authenticate your user, this action defines the auth variable in your Security and Firebase rules. This variable contains the user's auth payload, which includes that user's unique identifier (uid), and the name of the provider they logged with. Built-in providers also add provider-specific fields to auth, such as the user's name. If you implement a custom login provider, you can add your own fields to your user's auth payload.

Typically, you'll store all of your users in a single users node whose children are the uid values for every user. If you wanted to restrict access to this data such that only the logged-in user can see their own data, your rules would look something like this:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid"
      }
    }
  }
}

Next Steps

This just gave you a quick summary of the basics of Firebase security and told you what is possible with the flexible Security and Firebase rules. Continue reading on through the rules guide for more detailed explanations and many more example rules. You can also check out the full Security and Firebase Rules API documentation.