Firebase Firestore 사용법 – 구조 개념부터 CRUD 흐름까지 정리

주요 포인트 한눈에 보기

이 글은 Firebase를 처음 사용하는 개발자를 위해 firebase/firestore가 어떤 역할을 담당하는지, 그리고 Firestore를 사용할 때 반드시 이해해야 할 최소한의 구조와 흐름을 정리합니다. CRUD 전체를 나열하지 않고, 실제로 Firestore를 쓰기 전에 머릿속에 먼저 잡아야 할 개념과 준비 과정을 중심으로 설명합니다.

이론 개념 한 번에 정리

아래 내용은 Firestore를 사용하기 전에 반드시 이해해야 할 이론 개념 영역입니다. 코드 예제는 이후 섹션에서 다룹니다.

Firebase 안에서 Firestore의 위치

Firebase는 인증(Auth), 데이터베이스, 파일 저장소, 서버리스 함수 등을 하나의 플랫폼으로 묶어 제공하는 백엔드 서비스입니다. 이 중 Firestore는 애플리케이션의 상태와 데이터를 영구적으로 저장하고, 실시간 동기화를 지원하는 데이터베이스 역할을 담당합니다. Firestore는 Firebase 제품군 중 데이터 저장·조회(동기화 포함)를 책임지는 구성 요소이며, 실제 서비스에서는 Auth를 통한 사용자 식별과 Security Rules를 통한 접근 제어와 함께 설계됩니다.

firebase/firestore가 무엇인지 (역할)

firebase/firestore는 Firestore 데이터베이스와 통신하기 위한 전용 SDK입니다. Firebase SDK는 기능별로 모듈이 분리되어 있으며, Firestore 관련 API만 선택적으로 import하도록 설계되어 있습니다. 이를 통해 번들 크기를 줄이고, 필요한 기능만 명확히 사용하는 구조를 만들 수 있습니다. 실제 Firestore 초기화 코드는 앱 초기화 흐름과 함께 이후 섹션에서 한 번에 살펴봅니다.

데이터 구조 감각 (Collection / Document / 경로)

Firestore는 SQL 데이터베이스처럼 테이블 기반 구조를 사용하지 않습니다. 대신 Collection과 Document라는 두 가지 개념을 중심으로 데이터를 계층적으로 저장합니다. Collection은 문서들의 묶음이고, Document는 데이터가 저장되는 단위이며 내부에 필드(Map, Array, 원시값)를 가집니다. 구조를 이해할 때는 테이블보다 경로 기반 트리 구조로 생각하는 것이 중요합니다.

Firestore 사용을 위한 최소 준비 단계

Firestore를 사용하기 위해서는 Firebase 콘솔에서 프로젝트를 생성하고, 해당 프로젝트에 Firestore 데이터베이스를 활성화해야 합니다. 이후 웹 앱을 등록하고, SDK 설정 정보를 코드에 연결하는 과정이 필요합니다. 이때 firebaseConfig는 Firebase 콘솔에서 웹 앱을 등록할 때 제공되는 설정 객체입니다.

import { initializeApp } from 'firebase/app';
import { getFirestore } from 'firebase/firestore';

const app = initializeApp(firebaseConfig);
const db = getFirestore(app);

이 단계까지 완료되면 애플리케이션은 Firestore와 통신할 수 있는 상태가 됩니다. 이후 모든 컬렉션 접근과 문서 읽기·쓰기 동작은 이 db 인스턴스를 기준으로 이루어집니다.

데이터의 흐름

1. 저장(Create)

Firestore에서 가장 기본적인 데이터 저장 방식은 컬렉션 경로에 문서를 추가하는 것입니다. 이 방식은 문서 ID를 자동으로 생성하므로, 초기 단계에서 구조 이해에 집중하기 좋습니다.

import { collection, addDoc } from 'firebase/firestore';

await addDoc(collection(db, 'users'), {
  name: '홍길동',
  age: 20,
});

위 코드는 users 컬렉션 경로에 하나의 문서를 생성합니다. 내부적으로는 컬렉션 경로 확인 → 문서 ID 자동 생성 → 서버 저장 순서로 처리됩니다.

2. 읽기(Read)

Firestore에서 데이터 읽기는 단일 문서를 조회하는 방식과, 여러 문서를 목록으로 조회하는 방식으로 나뉩니다.

import { doc, getDoc } from 'firebase/firestore';

const snap = await getDoc(doc(db, 'users', userId));

if (snap.exists()) {
  console.log(snap.data());
}

단일 문서 조회는 doc으로 경로를 지정하고 getDoc으로 데이터를 가져옵니다. 문서가 존재하지 않을 수 있으므로 exists() 체크가 필요합니다.

import { collection, getDocs } from 'firebase/firestore';

const querySnap = await getDocs(collection(db, 'users'));

querySnap.forEach((doc) => {
  console.log(doc.id, doc.data());
});

여러 문서를 조회할 때는 컬렉션 경로를 기준으로 getDocs를 사용합니다. 결과는 반복 가능한 스냅샷 형태로 반환됩니다.

3. 수정(Update)

Firestore에서는 문서 전체를 덮어쓰거나, 필요한 필드만 부분적으로 수정할 수 있습니다. 일반적으로는 부분 수정 방식을 더 많이 사용합니다.

import { doc, updateDoc } from 'firebase/firestore';

await updateDoc(doc(db, 'users', userId), {
  age: 21,
});

updateDoc은 지정한 필드만 수정하며, 기존 문서의 다른 필드는 유지됩니다. 문서가 존재하지 않으면 오류가 발생합니다.

4. 삭제(Delete)

문서 삭제는 지정한 문서 경로를 기준으로 수행되며, 해당 문서만 제거됩니다.

import { doc, deleteDoc } from 'firebase/firestore';

await deleteDoc(doc(db, 'users', userId));

문서를 삭제해도 하위 컬렉션은 자동으로 삭제되지 않습니다. 하위 데이터까지 함께 제거하려면 별도의 처리 로직이 필요합니다.

실제 서비스에서는 위 CRUD 흐름을 기반으로 query, orderBy, limit, startAfter 등을 조합해 정렬·페이지네이션·조건 조회로 확장합니다. 이 문서에서는 기본 흐름만 다루며, 확장 사용법은 이후 단계에서 다룹니다.

정리

  • Firestore는 문서(Document) 기반의 NoSQL 데이터베이스입니다.
  • 데이터 구조는 Collection → Document → Subcollection 형태의 계층 구조를 가집니다.
  • 모든 데이터 접근은 경로(path)를 기준으로 이루어집니다.
  • 기본 시작 흐름은 initializeApp → getFirestore → collection/doc → addDoc 또는 setDoc 순서입니다.
  • 실서비스에서는 Auth와 Security Rules를 함께 설계해야 합니다.

FAQ

Q. Firestore는 SQL 데이터베이스인가요?
아닙니다. Firestore는 문서 기반 NoSQL 데이터베이스이며, 테이블과 조인 개념 대신 컬렉션과 문서 구조를 사용합니다.

Q. 컬렉션은 미리 만들어야 하나요?
아닙니다. 첫 문서를 추가하는 시점에 컬렉션은 자동으로 생성됩니다.

Q. 문서 ID를 자동 생성하는 이유는 무엇인가요?
충돌을 방지하고, 여러 클라이언트가 동시에 데이터를 저장하는 분산 환경에서도 안정적으로 고유성을 보장하기 위함입니다. 기본적으로는 자동 ID 생성을 사용하지만, 사용자 ID처럼 의미 있는 키가 필요한 경우에는 문서 ID를 직접 지정하는 방식도 함께 사용됩니다.

import { doc, setDoc } from 'firebase/firestore';

// 자동 ID: addDoc(collection(db, 'users'), data)

// 직접 ID 지정 (예: userId)
await setDoc(doc(db, 'users', userId), {
  name: '홍길동',
  age: 20,
});

Q. 면접에서 Firestore를 선택한 이유를 어떻게 설명하나요?
실시간 동기화, 서버리스 구조, 클라이언트 중심 개발에 적합하다는 점을 근거로 설명할 수 있습니다.

Q. Collection과 Document의 차이를 설명해보세요.
Collection은 문서들의 묶음이고, Document는 데이터가 저장되는 저장 단위이며 필드(Map, Array, 원시값)를 가집니다. 또한 하나의 문서 아래에는 하위 컬렉션이 올 수도 있습니다.

Q. Firestore 구조의 단점은 무엇인가요?
조인 연산이 없기 때문에 데이터 중복을 허용하는 설계가 필요하며, 초기 구조 설계가 중요합니다.

이 글이 마음에 드세요?

RSS 피드를 구독하세요!

댓글 남기기