Fix guide · high · firestore_collection_public_read
Firestore collection readable without authentication
A GET to https://firestore.googleapis.com/v1/projects/<project>/databases/(default)/documents/<collection> returned documents without an auth header. Your Firestore security rules permit anonymous reads on this collection.
Why it matters
Firestore's test-mode rules (allow read, write: if request.time < timestamp.date(...)) grant public access until a future date — usually 30 days from project creation. Apps that launch before the date passes ship with permissive rules. Even outside test mode, the most-copied StackOverflow snippet is match /{document=**} { allow read: if true; } because it's the fastest way to get the app working. Once that lands, every collection is enumerable via the Firestore REST API by anyone with the project ID.
How to fix it
Lock the rules to authenticated, scoped access. Console → Firestore Database → Rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Default: deny everything. Be explicit per collection below.
match /{document=**} {
allow read, write: if false;
}
// Users can read and write only their own user document.
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// Posts: signed-in users can read; only authors can write their posts.
match /posts/{postId} {
allow read: if request.auth != null;
allow create: if request.auth != null
&& request.resource.data.authorId == request.auth.uid;
allow update, delete: if request.auth != null
&& resource.data.authorId == request.auth.uid;
}
}
}
Key principles:
- Default-deny at the catch-all.
match /{document=**}withallow read, write: if falseensures any unprotected collection is denied, not open. - Check
request.auth != nullon every rule that requires sign-in. Anonymous Firebase Auth users have a UID, so this gates real users only when paired with provider checks. - Validate writes against
request.resource.data. This is what stops a logged-in user from settingauthorIdto someone else. - Test in the Rules Playground. Console → Rules → Simulator. Run unauthenticated and authenticated reads against each collection.
Full guide: /blog/firebase-rules-vibe-coded.
Did vibecheck flag this on your app?
If you reached this page from a vibecheck inspection report, the redacted match in your scan output is the exact string we found in your bundle. After applying the fix above, run the inspection again — the finding should clear.
Run another inspection