Firestore Security Rules — Complete Guide
In this tutorial, you'll learn about Firestore Security Rules. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Your Firestore data is read/writable by anyone (insecure rules), or your authenticated users can't access their own data.
Wrong Approach ❌
// Insecure: anyone can read/write everything
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true; // DANGER: open to the world!
}
}
}
Output: Anyone with your project ID can read/write all data.
Right Approach ✅
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// User profiles — only owner can access
match /users/{userId} {
allow read: if request.auth != null && request.auth.uid == userId;
allow write: if request.auth != null && request.auth.uid == userId
&& request.resource.data.name is string
&& request.resource.data.name.size() < 100;
}
// Public data — anyone can read, only admins can write
match /public/{document} {
allow read: if true;
allow write: if request.auth != null
&& get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == 'admin';
}
// Posts — authenticated users can create, owners can update
match /posts/{postId} {
allow create: if request.auth != null
&& request.resource.data.authorId == request.auth.uid
&& request.resource.data.title is string
&& request.resource.data.title.size() > 0;
allow read: if true;
allow update: if request.auth != null
&& resource.data.authorId == request.auth.uid;
allow delete: if request.auth != null
&& resource.data.authorId == request.auth.uid;
}
// Data validation example
match /reviews/{reviewId} {
allow write: if request.auth != null
&& request.resource.data.rating is number
&& request.resource.data.rating >= 1
&& request.resource.data.rating <= 5
&& request.resource.data.text is string
&& request.resource.data.text.size() <= 1000;
}
}
}
Output: Properly secured Firestore with user-specific access.
Prevention
- Start with
deny alland grant specific access. - Use
request.auth.uidfor user-specific rules. - Validate data types and sizes with
request.resource.data. - Use
get()andexists()for cross-document validation. - Test rules in Firebase Console > Firestore > Rules playground.
Common Mistakes with firestore security rule
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists - Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
- Using
returnto exit a function early instead of wrapping a pure value in the monad
These mistakes appear frequently in real-world ANDROID code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro