The goal of this tutorial is to introduce you to some common patterns in Firebase Security Rules. Firebase Security Rules provide the means to secure your data from unauthorized access. By the end of this tutorial, you will have a good understanding of how to use these rules to secure your Firebase applications.
This tutorial assumes that you have a basic understanding of Firebase and JavaScript.
Firebase Security Rules are JSON-like expressions that are used to secure your data stored in Firebase services, such as Firestore, Firebase Storage, and Realtime Database. These rules are evaluated on each read and write request to your database or storage.
A Firebase security rule has the following basic structure:
service {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if <condition>;
}
}
}
Here, service
specifies the Firebase service (Firestore, Storage, etc), match
is used to match incoming requests, and allow read, write
specifies the operations that are allowed or denied based on the condition.
Document-level access control allows or denies access to specific documents in your database.
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
}
This rule allows a user to read and write their own document.
Collection-level access control allows or denies access to all documents within a specific collection.
match /databases/{database}/documents {
match /users/{document=**} {
allow read: if request.auth != null;
}
}
This rule allows authenticated users to read all documents in the users
collection.
Role-based access control can be implemented by storing the user's role in their user document, and checking this role in the security rules.
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
}
}
This rule allows only admins to read and write all user documents.
Data validation can be done by checking the incoming request's request.resource.data
.
match /databases/{database}/documents {
match /users/{userId} {
allow create: if request.resource.data.keys().hasOnly(['name', 'email', 'password'])
&& request.resource.data.name is string
&& request.resource.data.email is string
&& request.resource.data.password is string;
}
}
This rule allows a document to be created only if it has the fields name
, email
, and password
, and these fields are of type string.
In this tutorial, we've covered how Firebase Security Rules work, and some common patterns including document-level access control, collection-level access control, role-based access control, and data validation.
Next, you could explore more advanced Firebase Security Rules patterns, such as hierarchical data access control and complex data validation.
role
field.match /users/{userId} {
allow delete: if request.auth.uid == userId;
}
match /users/{userId} {
allow create: if !exists(/databases/$(database)/documents/users/$(userId));
}
match /users/{userId} {
allow update: if request.auth.uid == userId && request.resource.data.role == resource.data.role;
}
Remember, practice is the key to mastering Firebase Security Rules! Keep experimenting with different rules and scenarios.