Use Cases

Claude Code के साथ Streamlining Firebase Development की Practical Guide

Claude Code का उपयोग करके guide to streamlining firebase development, real-world code examples के साथ।

Firebase と Claude Code

FirebaseはGoogleが提供するBaaSプラットform है।Claude Code का उपयोग करके、Firebaseの各serviceをintegration的にutilizationしたapplicationをefficientlydevelopmentでき है।

Firestore data設計

// 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);

// 型safeなコレクション参照
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");

CRUD操作

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

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

// fetch(pageネーション)
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,
  };
}

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

authentication

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
  );

  // userプロフィールを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);

  // 初回logイン時にプロフィールcreate
  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();

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

    // 著者の投稿数 update
    const authorRef = db.doc(`users/${post.authorId}`);
    await authorRef.update({
      postCount: FieldValue.increment(1),
    });

    // 通知 create
    await db.collection("notifications").add({
      type: "new_post",
      title: `नया記事: ${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 };
});

securityrule

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;
    }
  }
}

Claude Code सेのutilization

FirebasedevelopmentをClaude Code को requestする例 है।Supabaseとの比較はSupabaseintegrationdevelopment、authentication設計はJWTauthenticationpatternもदेखें。

Firebaseでチャットアプリを作って。
- Googleauthentication
- Firestoreでmessagemanagement
- リアルタイムupdate
- Cloud Functionsで通知processing
- securityruleのsettings

Firebaseके details के लिएFirebaseofficial documentationをदेखें。Claude Codeのutilization法はofficial documentationでconfirmでき है।

Summary

FirebaseはフルスタックapplicationのBaaS के रूप में非常にpowerful है।Claude Code का उपयोग करके、Firestore、Authentication、Cloud Functionsをintegration的にimplementationし、素早くプロダクト build किया जा सकता है。

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