Use Cases

Guia practica para optimizar el desarrollo con Firebase y Claude Code

Una guia practica para optimizar el desarrollo con Firebase usando Claude Code con ejemplos de codigo del mundo real.

Firebase y Claude Code

Firebase es una plataforma BaaS proporcionada por Google. Con Claude Code, puede desarrollar eficientemente aplicaciones que aprovechen de forma integrada los diversos servicios de Firebase.

Diseno de datos en Firestore

// lib/firebase.ts
import { initializeApp } from "firebase/app";
import { getFirestore, collection, doc } from "firebase/firestore";
import { getAuth } from "firebase/auth";

const app = initializeApp({
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
});

export const db = getFirestore(app);
export const auth = getAuth(app);

// Referencia de coleccion con seguridad de tipos
import {
  CollectionReference,
  DocumentData,
  collection as fbCollection,
} from "firebase/firestore";

function typedCollection<T extends DocumentData>(path: string) {
  return fbCollection(db, path) as CollectionReference<T>;
}

interface Post {
  title: string;
  content: string;
  authorId: string;
  authorName: string;
  published: boolean;
  tags: string[];
  createdAt: Date;
  updatedAt: Date;
}

export const postsRef = typedCollection<Post>("posts");

Operaciones CRUD

import {
  addDoc, updateDoc, deleteDoc, doc, getDoc, getDocs,
  query, where, orderBy, limit, startAfter,
  serverTimestamp, DocumentSnapshot,
} from "firebase/firestore";

// Creacion
async function createPost(data: Omit<Post, "createdAt" | "updatedAt">) {
  const docRef = await addDoc(postsRef, {
    ...data,
    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp(),
  });
  return docRef.id;
}

// Consulta (con paginacion)
async function getPosts(params: {
  pageSize?: number;
  lastDoc?: DocumentSnapshot;
  tag?: string;
}) {
  const { pageSize = 20, lastDoc, tag } = params;

  const constraints = [
    where("published", "==", true),
    orderBy("createdAt", "desc"),
    limit(pageSize),
  ];

  if (tag) {
    constraints.unshift(where("tags", "array-contains", tag));
  }

  if (lastDoc) {
    constraints.push(startAfter(lastDoc));
  }

  const q = query(postsRef, ...constraints);
  const snapshot = await getDocs(q);

  return {
    posts: snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data() })),
    lastDoc: snapshot.docs[snapshot.docs.length - 1],
    hasMore: snapshot.docs.length === pageSize,
  };
}

// Actualizacion
async function updatePost(id: string, data: Partial<Post>) {
  const ref = doc(postsRef, id);
  await updateDoc(ref, { ...data, updatedAt: serverTimestamp() });
}

Autenticacion

import {
  signInWithEmailAndPassword, createUserWithEmailAndPassword,
  signInWithPopup, GoogleAuthProvider, onAuthStateChanged, User,
} from "firebase/auth";

async function signUp(email: string, password: string, name: string) {
  const { user } = await createUserWithEmailAndPassword(auth, email, password);

  // Guardar perfil de usuario en Firestore
  await setDoc(doc(db, "users", user.uid), {
    email, name, createdAt: serverTimestamp(),
  });

  return user;
}

async function signInWithGoogle() {
  const provider = new GoogleAuthProvider();
  const { user } = await signInWithPopup(auth, provider);

  // Crear perfil en el primer inicio de sesion
  const userDoc = await getDoc(doc(db, "users", user.uid));
  if (!userDoc.exists()) {
    await setDoc(doc(db, "users", user.uid), {
      email: user.email, name: user.displayName,
      avatar: user.photoURL, createdAt: serverTimestamp(),
    });
  }

  return user;
}

// React Hook
function useAuth() {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    return onAuthStateChanged(auth, (user) => {
      setUser(user);
      setLoading(false);
    });
  }, []);

  return { user, loading };
}

Cloud Functions

// functions/src/index.ts
import { onDocumentCreated } from "firebase-functions/v2/firestore";
import { onCall, HttpsError } from "firebase-functions/v2/https";
import { getFirestore } from "firebase-admin/firestore";
import { initializeApp } from "firebase-admin/app";

initializeApp();
const db = getFirestore();

// Trigger de Firestore
export const onPostCreated = onDocumentCreated(
  "posts/{postId}",
  async (event) => {
    const post = event.data?.data();
    if (!post) return;

    // Actualizar conteo de publicaciones del autor
    const authorRef = db.doc(`users/${post.authorId}`);
    await authorRef.update({ postCount: FieldValue.increment(1) });

    // Crear notificacion
    await db.collection("notifications").add({
      type: "new_post",
      title: `Nuevo articulo: ${post.title}`,
      userId: post.authorId,
      createdAt: FieldValue.serverTimestamp(),
      read: false,
    });
  }
);

// Callable Function
export const publishPost = onCall(async (request) => {
  if (!request.auth) {
    throw new HttpsError("unauthenticated", "Authentication required");
  }

  const { postId } = request.data;
  const postRef = db.doc(`posts/${postId}`);
  const post = await postRef.get();

  if (!post.exists) {
    throw new HttpsError("not-found", "Post not found");
  }

  if (post.data()?.authorId !== request.auth.uid) {
    throw new HttpsError("permission-denied", "Not the author");
  }

  await postRef.update({
    published: true,
    publishedAt: FieldValue.serverTimestamp(),
  });

  return { success: true };
});

Reglas de seguridad

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /posts/{postId} {
      allow read: if resource.data.published == true;
      allow create: if request.auth != null
        && request.resource.data.authorId == request.auth.uid;
      allow update, delete: if request.auth != null
        && resource.data.authorId == request.auth.uid;
    }

    match /users/{userId} {
      allow read: if true;
      allow write: if request.auth != null
        && request.auth.uid == userId;
    }
  }
}

Uso con Claude Code

Ejemplo de como solicitar desarrollo con Firebase a Claude Code. Para comparacion con Supabase, consulte Desarrollo integrado con Supabase. Para diseno de autenticacion, consulte Patrones de autenticacion JWT.

Crea una aplicacion de chat con Firebase.
- Autenticacion con Google
- Gestion de mensajes con Firestore
- Actualizacion en tiempo real
- Procesamiento de notificaciones con Cloud Functions
- Configuracion de reglas de seguridad

Para mas detalles sobre Firebase, consulte la documentacion oficial de Firebase. Para el uso de Claude Code, consulte la documentacion oficial.

Resumen

Firebase es extremadamente poderoso como BaaS para aplicaciones full-stack. Con Claude Code, puede implementar de forma integrada Firestore, Authentication y Cloud Functions para construir productos rapidamente.

#Claude Code #Firebase #Firestore #Cloud Functions #BaaS