# Firebase pre-launch checklist

From BuildThenTested (https://buildthentested.com/stack/firebase/). 27 checks in the order we run them, most severe first. Each check links to a page with what it looks like, a self-check and a fix direction.

Defaults referenced are from Google's documentation, verified 2026-09-21. Tick a box only after you have seen the result yourself.

## Secrets and keys

- [ ] **Secrets committed to the code repository** (critical). Open your project on GitHub (or the code view in your builder) and look at the file list for .env, .env.local, .env.production, serviceAccountKey.json or firebase-adminsdk files.
  https://buildthentested.com/patterns/secrets-committed-to-repo/

## Data access

- [ ] **Firebase rules left in test mode** (critical). Open the Firebase console, choose your project, then Firestore Database (or Realtime Database, or Storage) and open the Rules tab.
  https://buildthentested.com/patterns/firebase-rules-open-test-mode/

- [ ] **Record ids accepted without an ownership check** (critical). Create two accounts in your app and add one record, such as an order or a note, in each.
  https://buildthentested.com/patterns/idor-on-record-ids/

- [ ] **Any signed-in user can read every row** (critical). In the Supabase dashboard open Authentication, then Policies. Row Level Security (RLS) is the per-row access rule set Postgres applies to each query, and this page shows each policy's expression.
  https://buildthentested.com/patterns/rls-any-authenticated-user-reads-all/

## Login and permissions

- [ ] **Admin routes without any login check** (critical). Open a private browsing window so you are signed out.
  https://buildthentested.com/patterns/admin-routes-without-auth/

- [ ] **Authorization enforced only in the browser** (critical). Sign in as a normal user and open developer tools (right-click, Inspect), then the Network tab.
  https://buildthentested.com/patterns/authorization-only-in-browser/

- [ ] **Default admin credentials left in place** (critical). In the builder's code view, search the whole project for admin@, password, seed and demo.
  https://buildthentested.com/patterns/default-admin-credentials/

- [ ] **Tokens trusted without server verification** (critical). Sign in, open developer tools (right-click, Inspect), go to the Network tab and pick a request to your own API that carries an Authorization header or a session cookie.
  https://buildthentested.com/patterns/jwt-accepted-without-server-verification/

- [ ] **Role chosen by the client at signup** (critical). Open your signup page, open developer tools (right-click, Inspect) and the Network tab, then submit the form with a test email.
  https://buildthentested.com/patterns/role-chosen-by-client-at-signup/

## AI features

- [ ] **No output validation before actions** (critical). List the things your AI feature can do beyond replying with text: run queries, call APIs, send messages, change records, fetch URLs, run code.
  https://buildthentested.com/patterns/no-output-validation-before-actions/

## Deploy and config

- [ ] **AI agent with production credentials** (critical). Open the folder the agent works in and look for .env, .env.local or similar files; note whether any value starts with sk_live_, contains the word prod, or is a service-role or admin key.
  https://buildthentested.com/patterns/ai-agent-with-production-credentials/

## Mobile

- [ ] **Secrets in the mobile app bundle** (critical). Open the project's .env files and app.json or app.config.js; list every variable whose name starts with EXPO_PUBLIC_ or that sits under extra.
  https://buildthentested.com/patterns/secrets-in-mobile-app-bundle/

## Secrets and keys

- [ ] **Third-party API key in the JavaScript bundle** (high). Open your live app in Chrome, right-click, choose Inspect, then open the Sources tab.
  https://buildthentested.com/patterns/api-key-in-javascript-bundle/

- [ ] **Secrets and internals in error messages and logs** (high). Open your live app, right-click, choose Inspect, then the Network tab. Trigger an error on purpose: submit a form with a field left blank, or visit an address like /api/anything-made-up.
  https://buildthentested.com/patterns/secrets-in-error-messages-and-logs/

## Data access

- [ ] **Uploaded files in a public storage bucket** (high). In the Supabase dashboard open Storage and look for the Public label on each bucket; in Firebase open Storage, then the Rules tab.
  https://buildthentested.com/patterns/storage-bucket-public/

## Login and permissions

- [ ] **Sessions that survive logout and password changes** (high). Sign in, open developer tools (right-click, Inspect), go to the Network tab and use Copy as cURL on a request that returns your account data.
  https://buildthentested.com/patterns/sessions-never-invalidated/

## Payments

- [ ] **Subscription state trusted from local storage** (high). Sign in to your app with a free account, press F12 to open developer tools, select the Application tab, then Local Storage on the left.
  https://buildthentested.com/patterns/subscription-state-trusted-from-local-storage/

## Reliability

- [ ] **No rate limiting on sensitive routes** (high). Open your app's login or "forgot password" page in Chrome, press F12 and choose the Network tab.
  https://buildthentested.com/patterns/no-rate-limiting/

## Data integrity

- [ ] **Deletes with no soft delete or audit trail** (high). In a test account, create a record in the app, then delete it using the app's own button.
  https://buildthentested.com/patterns/deletes-without-soft-delete-or-audit/

- [ ] **No backup that has ever been restored** (high). Open your database provider's dashboard and find the backups page (Supabase: Database, then Backups; Replit: the Database tool, then restore options).
  https://buildthentested.com/patterns/no-tested-backup-restore/

- [ ] **Race conditions on counters and balances** (high). Open the app in two browser tabs signed in to the same test account that has a limited balance, seat count or single-use coupon.
  https://buildthentested.com/patterns/race-conditions-on-counters-and-balances/

## Mobile

- [ ] **Offline state corrupting data** (high). On two phones (or a phone and the simulator) signed into the same account, put one in airplane mode and edit the same record on both.
  https://buildthentested.com/patterns/offline-state-corrupting-data/

## Reliability

- [ ] **Background jobs that fail silently** (medium). List every scheduled or background task your app has: on Vercel open Settings then Cron Jobs; on Supabase open Integrations then Cron, and Edge Functions; on Replit look for a Scheduled deployment.
  https://buildthentested.com/patterns/background-jobs-without-failure-handling/

- [ ] **Errors swallowed, spinner never stops** (medium). Open your app in Chrome and sign in as a normal user.
  https://buildthentested.com/patterns/errors-swallowed-ui-spins-forever/

## Performance

- [ ] **One database query per list item** (medium). Open a page in your app that shows a list (orders, projects, customers) in Chrome, press F12, choose the Network tab and filter by "Fetch/XHR".
  https://buildthentested.com/patterns/n-plus-one-queries/

- [ ] **List endpoints that return everything** (medium). Open your app's main list page in Chrome, press F12, choose the Network tab, filter by "Fetch/XHR" and reload.
  https://buildthentested.com/patterns/unpaginated-list-endpoints/

- [ ] **Whole table downloaded, filtered in the browser** (medium). Sign in to your app as a normal user, open a page that lists your own items, press F12, choose the Network tab, filter by "Fetch/XHR" and reload.
  https://buildthentested.com/patterns/whole-table-fetch-then-client-filter/

---

We test against a defined checklist and report what we find. We do not guarantee that an app is free of vulnerabilities. We are not a certified penetration-testing firm and do not issue compliance attestations. We do not rebuild your app; fixes are yours or your developer's, and we re-check them.

Questions: hello@buildthentested.com
