- Published on
Role-Based Access Control in Cloud Firestore
- Authors
- Name
- Aravind Chowdary Kamani
- @heytrulyaravind
Role-Based Access Control in Cloud Firestore
Firebase Security Rules allow you to implement role-based access control in your Cloud Firestore database efficiently. In this guide, we explain how to restrict access to sensitive operations by assigning specific privileges to different user roles.
Role-Based User Authorization
In our application, users can have multiple roles, each granting distinct privileges. Initially, roles were stored inside each user document, but this allowed users to modify their own roles. To prevent that, we separate role data so that only admin users can update roles.
Implementing Security Rules

Consider a data model where the users collection contains user documents. Each document has a field (an array of strings) that represents the roles assigned to the user. By moving role management to a secure area, we ensure that only authorized admins can change user roles.

For the users collection:
- Reading is allowed for any logged-in user.
- Updating or deleting a user document requires admin privileges. A custom function, hasAnyRole(), checks if the logged-in user holds any necessary roles.

For the posts collection (which separates user content from role data):
- A post is readable if it is published or if the requester is an admin (even when unpublished).
- Creating a post requires the request to include all mandatory fields and for the user to be the post’s owner.
- Updating a post allows only specific fields to be modified and may permit additional roles.
- Deletion is restricted to admin users, although you might optionally enable the post author to delete their own post based on your needs.
Custom Functions
Several custom functions enable these rules:
isLoggedIn(): Returns true if the request includes valid authentication.
Example:
function isLoggedIn() {
return request.auth != null;
}
hasAnyRole(roles): Checks if the authenticated user possesses at least one role from a given list.
Example:
function hasAnyRole(roles) {
return isLoggedIn() && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny(roles);
}
- isValidNewPost(): Ensures that a new post contains all the mandatory fields, that the requester is the owner, and that the timestamp is accurate.
- isValidUpdatedPost(): Validates that updates to a post are limited to allowed fields and that the content meets type and length restrictions.
Conclusion
Role-based access control significantly enhances the security of your Firestore database by ensuring that only authorized users perform sensitive operations. Customize these rules as needed to suit your application’s unique requirements.