Use Cases

Claude Code로 Firebase 개발 속도 높이기

Claude Code와 Firebase(Firestore, Authentication, Cloud Functions)를 조합해 풀스택 앱을 빠르게 구축하는 실전 가이드입니다.

Firebase와 Claude Code

Firebase는 Google이 제공하는 BaaS 플랫폼입니다. Claude Code를 활용하면 Firebase의 각 서비스를 유기적으로 엮은 애플리케이션을 빠르게 개발할 수 있습니다.

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

// 타입 안전한 컬렉션 참조
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";

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

// 조회(페이지네이션)
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,
  };
}

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

인증

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

  // 사용자 프로필을 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);

  // 최초 로그인 시 프로필 생성
  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;

    // 작성자의 게시 수 업데이트
    const authorRef = db.doc(`users/${post.authorId}`);
    await authorRef.update({
      postCount: FieldValue.increment(1),
    });

    // 알림 생성
    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 };
});

보안 규칙

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 활용 팁

Firebase 개발을 Claude Code에 맡기는 예시입니다. Supabase와의 비교는 Supabase 통합 개발, 인증 설계 패턴은 JWT 인증 패턴도 참고해 보세요.

Firebase로 채팅 앱 만들어줘.
- Google 인증
- Firestore로 메시지 관리
- 실시간 업데이트
- Cloud Functions로 알림 처리
- 보안 규칙 설정까지

Firebase의 자세한 내용은 Firebase 공식 문서에서, Claude Code 사용법은 공식 문서에서 확인할 수 있습니다.

정리

Firebase는 풀스택 앱을 위한 BaaS로 매우 강력합니다. Claude Code를 활용하면 Firestore, Authentication, Cloud Functions를 유기적으로 엮어 빠르게 제품을 만들어 낼 수 있습니다.

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

Claude Code 워크플로우를 한 단계 업그레이드하세요

지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.

무료 제공

무료 PDF: 5분 완성 Claude Code 치트시트

주요 명령어, 단축키, 프롬프트 예시를 A4 한 장에 정리했습니다.

PDF 다운로드
M

이 글을 작성한 사람

Masa

Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.