← 프로젝트 회고 · Backend
RETROSPECTIVE · 회고

Firestore getDocs는 실패해도 성공한다: 빌드 타임 조회의 함정

Backend

개인공부 글을 빌드 시점에 Firestore에서 읽어 정적 페이지로 만들도록 바꿨다. 그런데 네트워크가 막힌 환경에서 빌드를 돌려보니 에러 없이 성공했고, 글이 0개인 페이지가 만들어졌다.

원인

Firestore 웹 SDK의 getDocs()는 가능하면 서버 데이터를 기다리지만, 서버에 연결할 수 없으면 캐시된 결과를 반환하거나 실패할 수 있다. 빌드 환경에는 캐시가 비어 있으니 "빈 결과"가 정상 응답처럼 돌아온 것이다.

CI에서 네트워크가 한 번 삐끗하면 그대로 글이 하나도 없는 사이트가 배포될 수 있는 구조였다.

해결: 서버 응답을 강제

import { collection, getDocsFromServer } from "firebase/firestore";

// 서버에서 못 받아오면 throw → 빌드 실패 → 기존 배포 유지
const snapshot = await getDocsFromServer(collection(db, "studyPosts"));

getDocsFromServer()는 네트워크를 사용할 수 없으면 에러를 던진다. 이제 Firestore에 닿지 못하면 빌드가 실패하고, 배포 파이프라인이 멈춰서 이전 버전이 그대로 유지된다.

같은 요청이 여러 번 나가는 문제

generateStaticParams, 각 페이지, sitemap.ts가 모두 같은 데이터를 필요로 해서 Promise를 모듈 단위로 메모해 한 번만 조회하게 했다.

let allPostsPromise = null;
export function getAllStudyPosts() {
allPostsPromise ??= getDocsFromServer(collection(db, COLLECTION)).then(toPosts);
return allPostsPromise;
}

배운 점

  1. 클라이언트용 SDK는 "오프라인에서도 앱이 돌아가게" 설계되어 있어서, 빌드처럼 실패가 명확해야 하는 곳에서는 기본 동작이 오히려 위험할 수 있다.
  2. 빌드 타임 데이터는 "비어 있음"과 "못 가져옴"을 반드시 구분해야 한다.
Gunmo Lee
Firestore getDocs는 실패해도 성공한다: 빌드 타임 조회의 함정 | Gunmo's Dev Life