Firestore rules: the number-one mistake
The most common and most damaging Firebase mistake is shipping permissive Firestore security rules. A rule like "allow read, write: if request.auth != null" feels safe - it requires login - but it lets any authenticated user read and write every document in the collection, including other users' data.
- Authenticated is not authorized
Rules must check ownership (e.g. the document's userId equals request.auth.uid), not merely that a user is signed in.
- Default-open during development
Test-mode rules that "allow if true" sometimes survive to production. Confirm no collection is world-readable or world-writable.
- Validate writes in rules
Rules can enforce shape and field constraints. Generated apps usually skip this, trusting the client.
Auth and Storage gaps
Beyond Firestore, the same "authenticated ≠ authorized" mistake shows up in Storage rules, and client-side config gets misunderstood as a secret.
- Storage rules mirror the Firestore problem
Per-path ownership checks are needed, or any user can read and overwrite any file.
- Firebase config is public by design
The web config (apiKey, etc.) ships in the client - that's expected. Security comes from rules, not from hiding config. Don't rely on it being secret.
- Lock down privileged operations
Anything sensitive (role changes, billing, admin actions) belongs behind server-side code with the Admin SDK, never client-side rules alone.
Cost and scale on Firebase
Firestore bills per read, write, and delete, which makes inefficient access patterns a direct cost problem as well as a performance one. A list view that reads a whole collection, or a real-time listener fanned out across many clients, can run up a bill fast.
Review your read patterns for unbounded queries and overly broad listeners, and add the composite indexes your queries need before they fail or scan more than they should.
The pre-launch checklist
- Replace "auth != null" rules with ownership checks
Every document access must prove the user owns or may access it.
- Confirm no collection is in test-mode (allow if true)
Nothing world-readable or world-writable in production.
- Add per-path ownership to Storage rules
Mirror Firestore ownership for files.
- Enforce write shape/field constraints in rules
Don't trust the client to send valid documents.
- Move privileged operations to the Admin SDK
Role, billing, and admin actions run server-side only.
- Bound queries and listeners
Avoid whole-collection reads and overly broad real-time listeners.
- Create the composite indexes your queries need
Prevent failed or wasteful queries at scale.
Run this checklist on your repo, automatically
PeakStack scores every commit for security, scalability, and cost - with the exact line and a fix.
Request accessFAQ
Why are AI-generated Firebase apps often insecure?
Because the secure path requires writing real security rules, and generated code defaults to the permissive option - typically "allow if request.auth != null", which lets any logged-in user access everyone's data. The fix is ownership-based rules.
Is it bad that my Firebase API key is in the client?
No - the Firebase web config is public by design and shipping it in the client is expected. Your security comes entirely from Firestore and Storage rules, not from hiding the config. Don't treat the key as a secret, and don't rely on it being hidden.
How do I find these issues automatically?
PeakStack analyzes your repo on every commit and flags permissive rules, broken ownership checks, and unbounded queries with the specific location and a fix.