RTDB Data Modeling
RTDB is one JSON tree; every path is an API endpoint and reading a path downloads everything below it. Structure determines security, performance, pagination, and query shape — so design paths around the reads.
Steps
Inventory the reads. For each screen or listener: which entities, what order, what filters, how many items. Complete when every read is listed with its expected payload size.
Survey existing data (when a database exists).
rtdb_crawl_structuremaps the tree; the Realtime Database SDK'sgetsamples nodes. Complete when current shape and sizes are known.Design paths around the reads. Defaults that work:
- Top-level flat entity collections (
/users,/posts,/postSummaries) — never nest one entity type inside another. - Index tables for reverse lookups (
/userGroups/$uid/$groupId: true). - Denormalized summary nodes sized for list screens; detail nodes fetched per item.
- Push IDs for append-only lists (chronologically sortable, no collisions).
Complete when every inventoried read is served by one path whose full payload is what the screen needs.
- Top-level flat entity collections (
Plan writes for duplicated data. Every denormalized copy gets a multi-path fan-out write: a single call to the Realtime Database SDK's
updatewith several full paths as keys updates all copies atomically. Complete when each duplicated field lists the paths one logical write touches.Declare query indexes. Add
.indexOnin the security rules for every child key used withorderByChild. Complete when each ordered/filtered read has a matching.indexOn.State the rules implications. Flat top-level collections let each entity type carry its own access rule; index tables let membership gate reads. Hand the path map to the rules work (see the
rtdb-security-rulesskill). Complete when each path names who may read/write it.Seed and prove. Write representative data with the Realtime Database SDK's
set,push, andupdate, then read each inventoried path back withgetand confirm the payload matches step 1. Complete when reads return exactly the modeled shape.
Reference — anti-patterns
- Deep nesting under users or entities — one read drags the subtree.
- God nodes every client reads — fan-out hot spot and privacy hazard.
- Arrays with sequential numeric keys — concurrent writers collide; use push IDs.
- SQL-style normalization requiring client-side joins — duplicate instead.
- Multi-field filtering with no query-shaped path — RTDB queries take one
orderBy; precompute composite keys ("lang_level": "en_5") or restructure.