Firebase question
My Firestore rules say allow read, write: if true. How do I lock them down before launch?
Replace the rule before launch: allow read, write: if true on match /{document=**} lets anyone who guesses your project ID read, modify or delete every document, signed in or not, and Firebase's docs say never to use it in production. Start from rules that deny everything, then open each collection only as far as the app needs, usually to its owner with request.auth != null && request.auth.uid == userId. Test the new rules in the Rules Playground or the emulator, and publish them in the console or with firebase deploy --only firestore:rules. Rules apply to the web and mobile client libraries only: firebase-admin in your Next.js server code or Vercel functions bypasses them, so those routes need their own checks.
Where the open rule comes from
Creating a database in test mode starts with rules that, in Firebase's words, allow anyone to read and overwrite your data; production mode denies all reads and writes from mobile and web clients. If you manage rules with the Firebase CLI, they are in the file that firebase.json names, usually firestore.rules, and a CLI deploy overwrites the rules in the console. So check both: the file in the repo and the Rules tab, which shows what is live.
// Not for production: anyone can read and overwrite every document
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}Rules that are still too open
Firebase's list of insecure rules has three more after open access. request.auth != null on everything lets any signed-in user read and write every document. A check on the email domain without request.auth.email_verified trusts an address nobody confirmed. And allow read: if true on a collection that holds private fields publishes those fields.
How long a change takes
Firebase says updated rules can take up to a minute to affect new queries and listeners, and up to 10 minutes to reach active listeners. Test with a fresh page load after publishing.
Checklist
Lock them down, test, then deploy
- 01Find the open rules in the repo, then compare with the Rules tab in the Firebase console:
grep -rn "if true" firestore.rules grep -n "rules" firebase.json - 02Replace the catch-all with one match per collection. Owner-only access, from Firebase's docs:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, update, delete: if request.auth != null && request.auth.uid == userId; allow create: if request.auth != null; } } } - 03For a collection that is public by design, allow read: if true and keep writes to the owner, comparing request.auth.uid with an owner field on the document. Delete the match /{document=**} block: when several matches apply, access is allowed if any of them allows it, so a leftover catch-all keeps everything open. Collections you do not list are then closed.
- 04If a rule checks the email domain, also require request.auth.email_verified.
- 05Test the rules before you deploy, in the console's Rules Playground or with the emulator and @firebase/rules-unit-testing:
const testEnv = await initializeTestEnvironment({ projectId: 'demo-rules-test', firestore: { rules: fs.readFileSync('firestore.rules', 'utf8') }, }) const alice = testEnv.authenticatedContext('alice').firestore() const anon = testEnv.unauthenticatedContext().firestore() await assertSucceeds(getDoc(doc(alice, 'users/alice'))) await assertFails(getDoc(doc(alice, 'users/bob'))) await assertFails(getDoc(doc(anon, 'users/alice'))) - 06Deploy from the repo, so the file and the console stay the same:
firebase deploy --only firestore:rules - 07Check your server code: firebase-admin in a Route Handler, Server Action or Vercel function bypasses the rules, so it must check the signed-in user itself before it reads or writes for them.
- 08Load the deployed app signed out and as a second user, and confirm the reads that should fail now fail with a permission error.
Related
Related guides
Sources
Official docs behind this checklist
- Firebase, Fix insecure rules (Firestore)
- Firebase, Get started with Cloud Firestore Security Rules
- Firebase, Writing conditions for Cloud Firestore Security Rules
- Firebase, Structuring Cloud Firestore Security Rules (overlapping matches)
- Firebase, Get started with Cloud Firestore (test mode and production mode)
- Firebase, Manage and deploy Security Rules
- Firebase, Build unit tests (rules-unit-testing)
- Firebase, Test your Cloud Firestore Security Rules with the emulator
- Firebase FAQ, Are Firebase API keys secret?
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Is the Firebase config in my web app a secret?
No. Firebase's FAQ says its API keys are public by design: they identify your project and app, and access is controlled by IAM, Security Rules and App Check. So the rules have to protect the data, and Firebase suggests App Check on top, so that only your app's clients reach Firestore.
Can I keep allow read, write: if false?
Yes, if only your server reads and writes Firestore. Firebase's docs describe it as the setting for using Firestore as a server-only backend with the Admin SDK, which still has access; your browser code then gets permission errors.
Does request.auth != null make the data private?
Only from people without an account. Any signed-in user passes it, so add a condition on request.auth.uid, a role or an attribute for data that belongs to one user or team.