Use the Firebase CLI
Edit and deploy Rules using the Firebase CLI. Using the CLI allows you to keep your rules under version control with your application code and deploy rules as part of your existing deployment process.
Generate a configuration file
When you configure your Firebase project using the Firebase CLI, you create
a .rules
configuration file in your project directory. Use the following
command to start configuring your Firebase project:
Cloud Firestore
// Set up Firestore in your project directory, creates a .rules file firebase init firestore
Realtime Database
// Set up Realtime Database in your project directory, creates a .rules file firebase init database
Storage
// Set up Storage in your project directory, creates a .rules file firebase init storage
Edit and update your rules
Edit your rules directly in the .rules
configuration file. Make sure that any
edits you make in the Firebase CLI are reflected in the Firebase console, or
that you consistently make updates using either the Firebase console or the
Firebase CLI. Otherwise, you might overwrite any updates made in the Firebase
console.
Test your updates
Use the Firebase emulator to test your updates locally and confirm that your app's Rules exhibit the behavior you want.
Deploy your updates
Once you've updated and tested your Rules, deploy them to production. Use the following commands to selectively deploy your Rules alone or deploy them as part of your normal deployment process.
Cloud Firestore
// Deploy your .rules file firebase deploy --only firestore:rules
Realtime Database
// Deploy your .rules file firebase deploy --only database
Storage
// Deploy your .rules file firebase deploy --only storage
Use the Firebase console
You can also edit and deploy Rules from the Firebase console.
Edit and update your rules
- Open the Firebase console and select your project.
- Then, select Database or Storage from the product navigation.
- Database: Select a database, then click Rules to navigate to the Rules editor.
- Storage: Click Rules to navigate to the Rules editor.
- Edit your rules directly in the editor.
Test your updates
You can test your Rules behavior directly in the Firebase console, using the Rules simulator. Open the Simulator screen in the Rules editor, modify the settings and click Run. Look for the confirmation message at the top of the editor.
Deploy your updates
Once you're satisfied that your updates are what you expect, click Publish.
Use the Admin SDK
You can use the Admin SDK for Node.js to programmatically create, manage, and deploy security rules. With this programmatic access, you can:
- Implement custom tools, scripts, dashboards and CI/CD pipelines for managing rules.
- Manage rules more easily across multiple Firebase projects.
When updating rules programmatically, it is very important to avoid making unintended changes to the access control for your app. Write your Admin SDK code with security foremost in mind, especially when updating or deploying rules.
Another important thing to keep in mind is that Firebase security rules take a period of several minutes to fully deploy. When using the Admin SDK to deploy rules, make sure to avoid race conditions in which your app immediately relies on rules whose deployment is not yet complete. If your use case requires frequent updates to access control rules, consider solutions using Cloud Firestore, which is designed to reduce race conditions despite frequent updates.
Also note these limits:
- Rules must be smaller than 64 KiB of UTF-8 encoded text when serialized.
- A project can have at most 2500 total deployed rulesets. Once this limit is reached, you must delete some old rulesets before creating new ones.
Create and deploy Storage or Cloud Firestore rulesets
A typical workflow for managing security rules with the Admin SDK could include three discrete steps:
- Create a rules file (optional)
- Create a ruleset
- Release, or deploy, the new ruleset
The SDK provides a method to combine these steps into a single API call for Storage and Cloud Firestore security rules. For example:
const source = `service cloud.firestore {
match /databases/{database}/documents {
match /carts/{cartID} {
allow create: if request.auth.uid == request.resource.data.ownerUID;
allow read, update, delete: if request.auth.uid == resource.data.ownerUID;
}
}
}`;
// Alternatively, load rules from a file
// const fs = require('fs');
// const source = fs.readFileSync('path/to/firestore.rules', 'utf8');
await admin.securityRules().releaseFirestoreRulesetFromSource(source);
This same pattern works for Storage rules with releaseFirestoreRulesetFromSource()
.
Alternatively, you can create the rules file as an in-memory object, create the ruleset, and deploy the ruleset separately for closer control of these events. For example:
const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
const rs = await admin.securityRules().createRuleset(rf);
await admin.securityRules().releaseFirestoreRuleset(rs);
Update Realtime Database rulesets
To update Realtime Database rulesets with the Admin SDK, use the getRules()
and
setRules()
methods of admin.database
. You can retrieve rulesets in JSON
format, or as a string with comments included.
To update a ruleset:
const source = `{
"rules": {
"scores": {
".indexOn": "score"
"$uid": {
".read": "$uid == auth.uid",
".write": "$uid == auth.uid"
}
}
}
}`;
await admin.database().setRules(source);
Manage rulesets
To help manage large rulesets, the Admin SDK lets you list all existing rules
with admin.securityRules().listRulesetMetadata
. For example:
const allRulesets = [];
let pageToken = null;
while (true) {
const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
allRulesets.push(...result.rulesets);
pageToken = result.nextPageToken;
if (!pageToken) {
break;
}
}
For very large rulesets that reach the 2500-rule limit over time, you can create logic to delete the oldest rules on a fixed time cycle. For example, to delete ALL rule sets deployed for longer than 30 days:
const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
const promises = [];
allRulesets.forEach((rs) => {
if (new Date(rs.crateTime) < thirtyDays) {
promises.push(admin.securityRules().deleteRuleset(rs.name));
}
});
await Promise.all(promises);
console.log(`Deleted ${promises.length} rulesets.`);