Firebase Security Rules Best Practices

Firebase security rules best practices

Firebase's security model is genuinely powerful, but it's also one of the easiest places to make a quietly expensive mistake. Every new project starts locked down by default, which is the right instinct, but it's tempting to loosen a rule just to get something working during development, and that loosened rule has a way of making it into production and staying there unnoticed.

The short answer

Write rules around three principles: deny by default, scope every read and write to the data the requesting user actually owns, and validate data shape inside the rules themselves rather than trusting your app's client code to send well-formed data. A rule that only checks "is this user logged in" isn't really protecting anything, it's just checking a box.

Common mistakes worth knowing about

1. Rules left wide open from development

Firebase's test mode allows open read and write access for a limited window to make local development easier. It's meant to be temporary, but it's easy to forget it's there once the app is functionally working, and ship to production with rules that never actually got locked down.

2. Trusting client-side validation alone

Validating required fields and data types in your app code is good practice, but it isn't security. Anyone can call your Firebase project directly, bypassing your app entirely, so the rules themselves need to enforce data shape and types, not just decide who's allowed to write at all.

// Loose: only checks authentication, not data shape or ownership
match /orders/{orderId} {
  allow write: if request.auth != null;
}

// Tighter: checks ownership and validates the shape of what's being written
match /orders/{orderId} {
  allow write: if request.auth != null
    && request.resource.data.userId == request.auth.uid
    && request.resource.data.status is string
    && request.resource.data.total is number;
}

3. Inconsistent rules across related collections

A primary collection like orders often gets carefully scoped, while a related collection that references the same data, something like an assignment or status-tracking collection tied to those orders, gets left with looser rules because it feels secondary. The same data ends up protected one way in one place and exposed in another, which defeats the point of locking down the first collection at all.

4. Misreading identity in anonymous or phone-based auth

In apps using anonymous or phone-based authentication, the value in request.auth.uid doesn't always match the stable identifier your app actually uses to track a user, that mapping often lives in a separate user document instead. Writing rules that check request.auth.uid directly, when the app's real ownership logic depends on a different stored field, either blocks legitimate users unexpectedly or, worse, looks restrictive without actually restricting the right thing.

5. Forgetting to scope multi-tenant or multi-vendor data

In any system with more than one organization or vendor sharing the same database, "the user is authenticated" is not the same as "the user is allowed to see this specific record." Rules need an explicit check that the requesting user belongs to the vendor or organization that actually owns the record, not just that they're logged in at all.

6. Not testing rules before deploying

Rules can look correct when you read them and still allow or block the wrong thing once real nested data and document references are involved. The Firebase emulator suite lets you test rules against realistic data before they ever reach production, and it catches a category of mistakes that's nearly invisible from just reading the rules file.

A simple checklist

Why this matters more than it seems

A misconfigured security rule doesn't usually show up as a crash or an error message, it shows up as silent, ongoing data exposure that can go unnoticed for a long time, since the app keeps working normally for legitimate users the entire time the gap exists.

Frequently Asked Questions

Is Firebase secure by default?

New projects start locked down, but it's common for developers to temporarily loosen rules during development and forget to tighten them before launch, which is where most real-world exposure comes from.

Is client-side validation enough to protect my data?

No. Anyone can call your Firebase project directly, bypassing your app's client code entirely, so validation and ownership checks need to live in the security rules themselves.

How do I test security rules before deploying?

The Firebase emulator suite lets you run realistic test scenarios against your rules locally, which catches mistakes that aren't obvious just from reading the rules file.

What's different about securing a multi-vendor or multi-tenant app?

Rules need to check that the requesting user belongs to the specific vendor or organization that owns a record, not just that they're authenticated at all, otherwise one tenant's data can be exposed to another.

Not sure your Firebase rules are actually locked down?

Get a free AI audit and we'll review your rules before they become a problem.

Get Free AI Audit
Back to all articles