Choorai
Lv.2 BaaS

Firebase 시작하기

Backend-as-a-Service로 별도 백엔드 서버 없이 NoSQL 데이터베이스와 인증을 사용할 수 있습니다.

Firebase란?

  • Firestore - NoSQL 실시간 데이터베이스
  • Auth - 이메일/소셜 로그인 내장
  • Cloud Storage - 파일 저장 및 관리
  • Hosting - 정적 사이트 배포
  • Cloud Functions - 서버리스 함수 실행
  • 무료 티어 - Spark 플랜 무제한 프로젝트

1Firebase 프로젝트 생성

  1. console.firebase.google.com 에서 Google 계정으로 로그인
  2. 프로젝트 추가 클릭
  3. 프로젝트 이름 입력
  4. Google Analytics 설정 (선택 사항)
  5. 프로젝트 만들기 클릭
  6. 프로젝트 생성 후 웹 앱 추가 (</> 아이콘) 클릭하여 SDK 설정 정보 확인

정보

프로젝트 생성 후 대시보드에서 프로젝트 설정에 들어가면 API 키와 설정 정보를 확인할 수 있습니다.

2Firestore 데이터베이스 설정

대시보드에서 Firestore Database를 선택하고 데이터베이스를 생성하세요.

  1. 데이터베이스 만들기 클릭
  2. 프로덕션 모드 또는 테스트 모드 선택
  3. 리전 선택: asia-northeast3 (Seoul) 추천

보안 규칙 설정

Firestore규칙 탭에서 아래 보안 규칙을 적용하세요.

Firestore Rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /todos/{todoId} {
      allow read, write: if request.auth != null
        && request.auth.uid == resource.data.userId;
      allow create: if request.auth != null
        && request.auth.uid == request.resource.data.userId;
    }
  }
}

보안 규칙이 중요한 이유

보안 규칙 없이는 모든 사용자가 모든 데이터에 접근할 수 있습니다. request.auth.uid로 현재 로그인한 사용자만 자신의 데이터에 접근하도록 제한하세요.

3클라이언트 설정 (React)

의존성 설치

터미널
npm install firebase

환경 변수 설정

.env.local
# .env.local
VITE_FIREBASE_API_KEY=your-api-key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your-sender-id
VITE_FIREBASE_APP_ID=your-app-id

Firebase 콘솔 → 프로젝트 설정일반내 앱에서 확인하세요.

Firebase 클라이언트

src/lib/firebase.ts
// src/lib/firebase.ts
import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
  authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
  projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
  storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
  appId: import.meta.env.VITE_FIREBASE_APP_ID,
};

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

4CRUD 예제 (React + Firestore)

Firestore의 실시간 구독(onSnapshot)을 활용한 Todo 앱 예제입니다.

src/hooks/useTodos.ts
// src/hooks/useTodos.ts
import { useState, useEffect } from 'react';
import {
  collection,
  addDoc,
  getDocs,
  updateDoc,
  deleteDoc,
  doc,
  query,
  where,
  orderBy,
  onSnapshot,
  serverTimestamp,
} from 'firebase/firestore';
import { db, auth } from '../lib/firebase';

interface Todo {
  id: string;
  title: string;
  completed: boolean;
  userId: string;
  createdAt: any;
}

export function useTodos() {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const user = auth.currentUser;
    if (!user) return;

    const q = query(
      collection(db, 'todos'),
      where('userId', '==', user.uid),
      orderBy('createdAt', 'desc')
    );

    // 실시간 구독
    const unsubscribe = onSnapshot(q, (snapshot) => {
      const items = snapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      })) as Todo[];
      setTodos(items);
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  // 생성
  const addTodo = async (title: string) => {
    const user = auth.currentUser;
    if (!user) throw new Error('Not authenticated');

    await addDoc(collection(db, 'todos'), {
      title,
      completed: false,
      userId: user.uid,
      createdAt: serverTimestamp(),
    });
  };

  // 수정
  const toggleTodo = async (id: string, completed: boolean) => {
    await updateDoc(doc(db, 'todos', id), { completed });
  };

  // 삭제
  const removeTodo = async (id: string) => {
    await deleteDoc(doc(db, 'todos', id));
  };

  return { todos, loading, addTodo, toggleTodo, removeTodo };
}

5인증 예제 (선택)

Firebase Auth를 사용하면 이메일/비밀번호 로그인을 쉽게 구현할 수 있습니다.

src/hooks/useAuth.ts
// src/hooks/useAuth.ts
import { useState, useEffect } from 'react';
import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut as firebaseSignOut,
  onAuthStateChanged,
  User,
} from 'firebase/auth';
import { auth } from '../lib/firebase';

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

  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setUser(user);
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  // 회원가입
  const signUp = async (email: string, password: string) => {
    const { user } = await createUserWithEmailAndPassword(
      auth, email, password
    );
    return user;
  };

  // 로그인
  const signIn = async (email: string, password: string) => {
    const { user } = await signInWithEmailAndPassword(
      auth, email, password
    );
    return user;
  };

  // 로그아웃
  const signOut = async () => {
    await firebaseSignOut(auth);
  };

  return { user, loading, signUp, signIn, signOut };
}

소셜 로그인

Google, GitHub, Facebook 등 소셜 로그인도 지원합니다. Firebase 콘솔 → AuthenticationSign-in method에서 설정하세요.

언제 Firebase를 사용하면 좋을까요?

추천하는 경우

  • - 빠르게 프로토타입을 만들 때
  • - 실시간 데이터 동기화가 필요할 때
  • - 모바일 앱과 웹을 동시에 지원할 때
  • - Google 생태계와 연동이 필요할 때

고려가 필요한 경우

  • - 복잡한 관계형 쿼리가 필요할 때
  • - SQL 기반 데이터 분석이 중요할 때
  • - 벤더 종속이 우려될 때
  • - 대량 데이터 내보내기가 빈번할 때

다음 단계

마지막 업데이트: 2026년 2월 22일 · 버전: v0.0.1

피드백 보내기

입력한 내용으로 새 이슈 페이지를 엽니다.

GitHub 이슈로 보내기