Diseña Firestore con Claude Code: empieza por consultas, no colecciones
Flujo práctico para diseñar Firestore con Claude Code: esquema guiado por consultas, índices, costos, reglas de seguridad y TypeScript.
Firestore se diseña desde las preguntas de la app
Soy Masa, operador de claudecode-lab.com.
Con Firestore, el error típico es empezar por colecciones bonitas: users, posts, comments. Parece ordenado, pero cuando aparecen pantallas reales —últimos posts publicados, posts por autor, drafts del panel admin, páginas por tag— el diseño empieza a crujir.
Firestore no es una base SQL donde arreglás todo luego con joins. Conviene listar primero las consultas y recién después diseñar documentos.
Documentación oficial usada como referencia:
Paso 1: pedile a Claude Code un inventario de consultas
claude -p "
Diseñá Firestore para un CMS.
Antes de proponer colecciones, listá las consultas.
Pantallas:
- posts publicados por publishedAt desc
- página de autor por authorId
- drafts del admin por updatedAt desc
- página de tag
- bandeja de contactos por status y createdAt asc
Devolvé where/orderBy/limit e índices compuestos.
"
El resultado útil es una tabla:
| Pantalla | where | orderBy | Índice |
|---|---|---|---|
| Lista | status == "published" | publishedAt desc | status, publishedAt desc |
| Autor | authorId, status | publishedAt desc | authorId, status, publishedAt desc |
| Admin | status == "draft" | updatedAt desc | status, updatedAt desc |
Paso 2: duplicá campos pequeños cuando mejora la lectura
export interface PostDoc {
id: string;
slug: string;
title: string;
description: string;
status: "draft" | "published" | "archived";
lang: "ja" | "en" | "es" | "ko";
authorId: string;
authorName: string;
authorAvatarUrl: string;
tagSlugs: string[];
tagNames: string[];
publishedAt: FirebaseFirestore.Timestamp | null;
updatedAt: FirebaseFirestore.Timestamp;
createdAt: FirebaseFirestore.Timestamp;
}
Sí, authorName está duplicado. Pero una lista de 20 posts no debería disparar 20 lecturas adicionales solo para mostrar nombres.
Paso 3: validá escrituras con Zod
import { z } from "zod";
export const CreatePostSchema = z.object({
slug: z.string().min(3).max(120).regex(/^[a-z0-9-]+$/),
title: z.string().min(1).max(120),
description: z.string().max(160),
lang: z.enum(["ja", "en", "es", "ko"]),
authorId: z.string().min(1),
authorName: z.string().min(1),
authorAvatarUrl: z.string().url(),
tagSlugs: z.array(z.string()).max(8),
tagNames: z.array(z.string()).max(8),
});
export async function createDraftPost(input: unknown) {
const parsed = CreatePostSchema.parse(input);
const ref = db.collection("posts").doc();
await ref.set({
id: ref.id,
...parsed,
status: "draft",
publishedAt: null,
createdAt: FieldValue.serverTimestamp(),
updatedAt: FieldValue.serverTimestamp(),
});
}
Paso 4: versioná los índices
{
"indexes": [
{
"collectionGroup": "posts",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "lang", "order": "ASCENDING" },
{ "fieldPath": "status", "order": "ASCENDING" },
{ "fieldPath": "publishedAt", "order": "DESCENDING" }
]
}
],
"fieldOverrides": [
{
"collectionGroup": "posts",
"fieldPath": "body",
"indexes": []
}
]
}
Paso 5: reglas con escenarios de ataque
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function isAdmin() {
return request.auth != null
&& request.auth.token.role == "admin";
}
match /posts/{postId} {
allow read: if resource.data.status == "published" || isAdmin();
allow create, update, delete: if isAdmin();
}
}
}
Probá escenarios concretos: usuario anónimo leyendo drafts, usuario común publicando posts, formularios inyectando campos de admin.
Resultado
Cuando apliqué este flujo a diseños pequeños de artículos, contactos y logs, reescribí más de la mitad del primer esquema. La mejora vino de pedirle a Claude Code una tabla de consultas antes de pedirle código.
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Lleva tu flujo con Claude Code al siguiente nivel
50 plantillas de prompts probadas en producción, listas para copiar y pegar en Claude Code.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
Que es Codex Automations y como dejar que la IA gestione contenido mientras duermes
Guia practica para usar Codex Automations en analitica, articulos, CTA, despliegue y monetizacion.
Claude Code × GCP Cloud Functions Guía Completa | Desarrollo Serverless Ultrarrápido
Optimiza GCP Cloud Functions con Claude Code. Implementa triggers HTTP/Pub/Sub/Firestore, pruebas locales y automatización de despliegues con ejemplos de código reales de la experiencia de Masa.
Claude Code × GCP Cloud Run Guía Completa | Despliegue automático de contenedores serverless
Acelera los despliegues en GCP Cloud Run con Claude Code. Guía completa con ejemplos de código reales: generación de Dockerfile, auto-escalado, pipelines CI/CD e integración con Secret Manager.