¿Construyes con Firestore? Estas 15 reglas te ahorrarán los errores más comunes. Ya sea que estés comenzando tu primer proyecto Firebase o escalando uno existente, estas mejores prácticas cubren todo desde modelado de datos hasta optimización de costos — aprendidas de aplicaciones en producción reales.
Reglas de Modelado de Datos
Cómo estructuras tus datos determina todo lo demás — rendimiento de consultas, costos y mantenibilidad. Hazlo bien desde el principio.
1. Prefiere colecciones planas sobre anidación profunda
Las subcolecciones profundamente anidadas hacen las consultas más difíciles y crean acoplamiento fuerte. Mantén tu jerarquía de colecciones poco profunda — usualmente 1-2 niveles. Usa colecciones de nivel raíz con referencias de documentos en lugar de anidar todo bajo un padre. Por ejemplo, almacena orders como una colección raíz con un campo userId en lugar de anidar bajo users/{id}/orders — a menos que solo consultes pedidos por usuario.
2. Desnormaliza datos para rendimiento de lectura
En SQL normalizas para evitar duplicación. En Firestore, desnormalizas para evitar múltiples lecturas. Si tu interfaz muestra el nombre de un usuario junto a cada comentario, almacena authorName directamente en cada documento de comentario — no fuerces una lectura separada a la colección users. Acepta el compromiso: las escrituras son más complejas, pero las lecturas son rápidas y económicas.
3. Usa subcolecciones para relaciones uno a muchos sin límite
Cuando un documento puede tener cientos o miles de elementos relacionados (mensajes en un chat, pedidos de un usuario), usa subcolecciones. A diferencia de los arrays dentro de documentos, las subcolecciones pueden contener elementos ilimitados y soportan consultas eficientes con paginación. Ejemplo: chats/{chatId}/messages/{messageId}.
4. Mantén los documentos bajo 20 KB para rendimiento óptimo
El límite duro de Firestore es 1 MB por documento, pero apunta a menos de 20 KB. Los documentos grandes desperdician ancho de banda cuando solo necesitas unos pocos campos — y Firestore cobra por lectura de documento independientemente del tamaño. Si un documento está creciendo, divídelo en subcolecciones o una colección separada.
5. Evita arrays para datos consultables
Los arrays en Firestore tienen limitaciones: no puedes actualizar elementos individuales, las consultas array-contains solo soportan una por consulta, y los arrays no escalan bien más allá de unos cientos de elementos. Para etiquetas o categorías usa array-contains, pero para relaciones o listas crecientes, usa subcolecciones o campos de mapa en su lugar.
Optimización de Consultas
Las consultas de Firestore son rápidas por diseño, pero solo si trabajas con sus restricciones — no en su contra.
6. Crea índices compuestos proactivamente
Firestore requiere un índice para cada patrón de consulta único. En lugar de esperar mensajes de error, planifica tus índices por adelantado. Defínelos en firestore.indexes.json y despliega con firebase deploy --only firestore:indexes. Cada combinación de where + orderBy necesita su propio índice compuesto.
7. Usa paginación basada en cursor, no offsets
Nunca uses paginación basada en offset en Firestore — aún lee (y cobra por) todos los documentos omitidos. En su lugar, usa startAfter() con el último documento de la página anterior. Esto es más rápido y económico, ya que Firestore solo lee los documentos que realmente necesitas.
8. Limita los resultados de consulta explícitamente
Siempre agrega .limit() a tus consultas. Sin él, Firestore devuelve cada documento coincidente — que podrían ser millones. Incluso si crees que una colección es pequeña hoy, no lo será en seis meses. Un buen valor predeterminado es 20-50 documentos por consulta.
9. Evita leer colecciones completas
Si te encuentras haciendo collection('users').get() sin filtros, tu modelo de datos necesita replanteamiento. Usa consultas de agregación (count(), sum()) para analíticas, y siempre filtra con where() para consultas de visualización. Leer todos los documentos es la causa #1 de facturas inesperadas de Firestore.
Patrones de Reglas de Seguridad
Las reglas de seguridad de Firestore son tu única validación del lado del servidor. Si las haces mal, toda tu base de datos queda expuesta.
10. Siempre valida tipos de campo en las reglas
No solo verifiques si un campo existe — valida su tipo. Un cliente malicioso podría enviar age: "not a number" si solo verificas request.resource.data.age != null. Usa is string, is number, is bool para forzar tipos a nivel de reglas de seguridad.
11. Usa reglas granulares por colección
Nunca uses allow read, write: if true a nivel de base de datos. Escribe reglas específicas para cada colección: quién puede leer, quién puede crear, quién puede actualizar, quién puede eliminar. Comienza con todo denegado y abre acceso incrementalmente. Usa patrones match para subcolecciones.
12. Nunca confíes en datos del lado del cliente
El cliente puede enviar cualquier dato que quiera. Valida campos requeridos, verifica tipos de datos, impone valores enum y verifica que los campos de referencia apunten a documentos reales. Usa request.auth para verificar que el usuario es quien dice ser, y resource.data para comparar contra valores existentes.
Optimización de Costos
Los precios de Firestore se basan en lecturas, escrituras y almacenamiento. Pequeños cambios en cómo consultas pueden tener grandes impactos en tu factura.
13. Agrupa escrituras en lotes para reducir operaciones
Usa writeBatch() o runTransaction() para combinar múltiples escrituras en una sola operación. Un lote de 500 escrituras cuesta lo mismo que 500 escrituras individuales en términos de operaciones, pero reduce viajes de red y asegura atomicidad. Limita los lotes a 500 operaciones máximo.
14. Cachea documentos leídos frecuentemente
El SDK cliente de Firestore tiene persistencia offline integrada — habilítala. Para aplicaciones del lado del servidor, implementa una capa de caché (Redis, en memoria) para documentos que cambian infrecuentemente pero se leen constantemente, como configuración de app o perfiles de usuario. Cada lectura cacheada es una lectura que no pagas.
15. Usa consultas de agregación en lugar de leer todos los docs
¿Necesitas un conteo de documentos? Usa countQuery() en lugar de obtener todos los documentos y contar del lado del cliente. Las consultas de agregación de Firestore (count(), sum(), average()) leen entradas de índice en lugar de documentos completos, costando aproximadamente 1/1000 por entrada.
Extra: Documenta la Estructura de tu Base de Datos
Todas estas mejores prácticas son inútiles si tu equipo no puede encontrarlas. A medida que tu base de datos Firestore crece, llevar el registro de estructuras de colecciones, tipos de campos y reglas de validación se convierte en un desafío. JSON Schema te da una forma estándar de describir la estructura de tu base de datos — y herramientas como FireSchema convierten esos esquemas en documentación interactiva y navegable que todo tu equipo puede consultar.
💡 Consejo: Crea un archivo .schema.json para cada colección documentando sus campos, tipos y reglas de validación. Esto se convierte en la única fuente de verdad de tu equipo.
Siguientes Pasos
Continúa aprendiendo sobre Firestore y documentación de bases de datos: