Use Cases

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:

PantallawhereorderByÍndice
Listastatus == "published"publishedAt descstatus, publishedAt desc
AutorauthorId, statuspublishedAt descauthorId, status, publishedAt desc
Adminstatus == "draft"updatedAt descstatus, 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.

#claude-code #gcp #firestore #database #typescript #query-design
Gratis

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.

Masa

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.