Use Cases

Panduan Praktis Streamlining Firebase Development dengan Claude Code

Panduan praktis tentang streamlining firebase development menggunakan Claude Code dengan contoh kode dunia nyata.

Firebase と Claude Code

Firebase Google penyediaan BaaSplatform.Claude Code 使えば、Firebase 各service integrasi的 pemanfaatan aplikasi efisien pengembangan bisa dilakukan.

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

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

Operasi CRUD

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

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

// pengambilan(pagination)
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,
  };
}

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

Autentikasi

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

  // penggunaprofil Firestore penyimpanan
  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);

  // 初回login時 profilpembuatan
  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();

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

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

    // notifikasi pembuatan
    await db.collection("notifications").add({
      type: "new_post",
      title: `新しいartikel: ${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 };
});

セキュリティルール

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

Pemanfaatan dengan Claude Code

Firebasepengembangan Claude Code 依頼 例.Supabase dan 比較 Supabaseintegrasipengembangan、認証設計 JWT認証pola juga bisa dijadikan referensi.

Firebase dengan チャットaplikasi buatkan.
- Google認証
- Firestore dengan pesanmanajemen
- リアルタイムpembaruan
- Cloud Functions dengan notifikasipemrosesan
- セキュリティルール pengaturan

Firebase 詳細 Firebase公式dokumen silakan lihat.Claude Code pemanfaatan法 公式dokumen konfirmasi bisa dilakukan.

Summary

Firebase full-stackaplikasi BaaS sebagai 非常 強力.Claude Code 使えば、Firestore、Authentication、Cloud Functions integrasi的 implementasiし、素早くプロダクト pembangunan bisa dilakukan.

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