You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
- Three Types of Rules
- Special Variables
- Common Firebase Database Rules and Scenarios
- No security. Anybody can read or write
- Full security. Nobody can read or write
- Only authenticated users can read and write
- Users can only write data they own
- Only authorized moderator users can write to the database
- You want to validate input meets a certain criteria
- Ensure certain child attributes are present
- Ensuring that data does (or does not) exist before writing
- Common Pitfall - Cascading Rules
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Understanding Firebase Database Rules by Example
Episode 11 written by Jeff DelaneySecurity is a critical concern for any web application. A secure web app must prevent unauthorized database operations, as well as validate the integrity of incoming data.
Firebase allows you to define database security logic in a JSON file that corresponds to the structure of your database.
A NoSQL database is just a series of nodes – and the database.rules.json file allows you to control security and data validation at each node.
You can work with the database rules from an Angular project, or from the Firebase console. Personally, I prefer working from the console because it allows you to easily publish and test your rules.
Three Types of Rules
There are three types of rules you can set - read, write, and validate. Read controls access to data. Write controls creating, editing, or deleting data. Validate controls the format of data.
You can use any combination of these rules together, or none at all.
Special Variables
There are also several built-in variables that give you access to Firebase resources.
- auth - Gives you access to the user auth state.
- root - The root of the database and can be traversed with
.child('name')
. - data - Data state before an operation
- newData - Data after an operation (the incoming data)
- now - Unix epoch timestamp
- ${child key} - Wildcard for any child key at a database node.
Common Firebase Database Rules and Scenarios
Let’s run through the most common security scenarios you might run into.
No security. Anybody can read or write
"rules": { |
Full security. Nobody can read or write
"rules": { |
Only authenticated users can read and write
"rules": { |
Users can only write data they own
Let’s assume you have an app that has user comments nested under their user id. You can prevent other users from accessing or writing this data by comparing the auth.uid
to the uid database key.
"rules": { |
Only authorized moderator users can write to the database
Let’s imagine you only allow trusted users who have been promoted to moderators to modify data. You will first need to save an attribute in the database, then check that the authorized user has this attribute. The root variable allows you to traverse the database to verify that the moderator attribute is true.
"rules": { |
You want to validate input meets a certain criteria
You don’t want users to just post anything to your database. Let’s validate a post is at least 1 character, limited to 140 character long, and must be a string value. You can string together validators with logical operators.
SEE Gist Below
Ensure certain child attributes are present
Let’s say new posts must have username and a timestamp.
"rules": { |
### Validate that a timestamp is not a future value
The now
variable can be used to check the input timestamp against the current time in Firebase.
SEE Gist Below
Ensuring that data does (or does not) exist before writing
By checking if data or newData exists, you can control whether a user can perform create, update, or delete operations.
SEE Gist Below
Common Pitfall - Cascading Rules
On a final note, let’s look at a common pitfall with firebase security. You cannot grant access to data, then revoke it later. However, you can do the opposite - revoke access, then grant it back later. That being said, it is usually best to deny access by default, then grant access when the ideal conditions have been satisfied deeper in the tree.
The second rule in the tree will not revoke the access already granted
You might think this write should be denied, but it will be allowed because the first rule defined takes priority. You would want to refactor your rules to prevent access by default.
That’s it for database rules. You should be able to use a combination of these principles for virtually any database security configuration.