{}FireSchema

Why Firestore Is Confusing (And How to Fix It)

The 5 mental shifts SQL developers need to make — and tools that help

If you've ever stared at your Firestore console wondering 'where did I put that data?' or 'why is this query not working?', you're not alone. Firestore is powerful, but its NoSQL nature trips up most developers — especially those coming from SQL databases. Let's break down exactly why it's confusing and what you can do about it.

Why Firestore Feels So Different

If you've used MySQL, PostgreSQL, or any SQL database, you've trained your brain to think in tables, rows, and joins. Firestore throws all of that away. There are no tables — just collections. No rows — just documents. No joins — just denormalized data. And no schema enforcement — documents in the same collection can have completely different fields.

The mental model shift:

SQL

Tables with fixed columns → Rows follow a strict schema → JOINs combine related data → Normalization avoids duplication

Firestore

Collections with flexible documents → Each document can differ → No JOINs — denormalize instead → Duplication is expected and encouraged

5 Mistakes Every Firestore Beginner Makes

1. Trying to normalize everything

In SQL, you normalize to avoid data duplication. In Firestore, this forces you to make multiple reads to assemble a single view. Instead, store the data where you read it — even if it means duplicating a user's display name in every comment they write.

2. Using arrays for relationships

Storing an array of user IDs in a document seems logical, but Firestore arrays have severe limitations: you can't query individual elements efficiently, and they don't scale past a few thousand items. Use subcollections or a separate collection with references instead.

3. Putting everything in one document

Firestore charges per document read, so it's tempting to cram everything into one big document. But documents have a 1 MB limit, and reading a 500 KB document when you only need 2 fields wastes bandwidth and increases costs. Split into focused, smaller documents.

4. Ignoring query limitations upfront

Firestore can't do inequality filters on multiple fields in a single query, can't do native full-text search, and requires indexes for compound queries. Design your data model around your queries from day one — not the other way around.

5. Not documenting the structure

Without a schema, your Firestore database becomes a black box. New team members guess at field names, typos cause silent bugs, and nobody knows if a field is required or optional. This is the most common and most damaging mistake.

How to Bring Structure to Your Firestore Database

The good news: you can add structure to Firestore without giving up its flexibility. Here are three practical steps:

1Design your queries first

Before creating collections, list every screen in your app and what data it needs. This query-first approach ensures your data model serves your UI — the opposite of SQL thinking where you design tables first.

2Use consistent field names and types

Decide on conventions early: camelCase or snake_case? Timestamps as Firestore Timestamps or ISO strings? Required fields vs optional? Write these decisions down somewhere your team can find them.

3Document your collections with JSON Schema

JSON Schema is an open standard that lets you describe the structure of each collection: field names, types, which are required, what values are valid. It's like a blueprint for your database — and it doubles as documentation that stays accurate if you keep it in your repository.

What This Looks Like in Practice

Here's a simple JSON Schema describing a Firestore users collection. Notice how every field has a type and description — anyone on your team can understand the data model at a glance:

schemas/users.schema.jsonJSON
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "collection": "users",
  "description": "Registered app users",
  "schema": {
    "type": "object",
    "properties": {
      "displayName": {
        "type": "string",
        "description": "User's full name"
      },
      "email": {
        "type": "string",
        "format": "email",
        "description": "Login email address"
      },
      "role": {
        "type": "string",
        "enum": ["admin", "editor", "viewer"],
        "description": "Access control role"
      },
      "createdAt": {
        "type": "string",
        "format": "date-time",
        "description": "Account creation timestamp"
      }
    },
    "required": ["displayName", "email", "role", "createdAt"]
  }
}

This schema file lives in your repository, gets reviewed in PRs, and serves as the single source of truth for your users collection. No more guessing.

Turn Schemas into Interactive Documentation

Once you have schema files for your collections, tools like FireSchema can render them as interactive, browsable documentation — similar to how Swagger UI works for REST APIs, but designed for NoSQL databases. It's free, open-source, and takes about 5 minutes to set up.

Next Steps

Continue building your Firestore knowledge:

Try FireSchema

Quick Start Guide