Firebase 초기화 구조: Next.js firebase.ts 설계 기준

··설명 약 6분·작성: 해비·블로그 소개

Next.js에서 Firebase 웹 SDK 초기화 모듈과 서버 경계는 어떻게 설계하나요?

Next.js의 Firebase 웹 SDK는 한 모듈에서 초기화해 재사용합니다. 브라우저 전용 코드와 Admin SDK를 나누고 누락 변수는 값 대신 키 이름으로 알리세요. projectId가 목표 프로젝트와 맞는지 확인한 뒤 로그인·권한을 검증합니다.

적용 조건·범위: client-only는 서버 코드에서 잘못 가져오는 것을 막는 표시입니다. 화면 컴포넌트에는 use client를 쓰고 그 컴포넌트가 이 모듈을 가져오도록 합니다. Admin SDK와 서버 세션 검증은 별도 server-only 모듈에서 다룹니다. 브라우저 currentUser를 서버가 자동으로 공유한다고 생각하면 보호 API가 비게 됩니다.

본문 근거: firebase.google.com/docs/web/setup · nextjs.org/docs/app/guides/environment-variables

이 글의 질문과 결과

질문: Next.js에서 Firebase 설정을 어디에 두고, 내 앱이 의도한 프로젝트에 연결됐는지 어떻게 확인할까요? 결과물은 한 개의 client-only 초기화 모듈과 대상 projectId 확인 기록입니다. 로그인·DB 권한은 다음 글에서 검증합니다.

학습 목표와 사전 지식

목표: Next.js에서 Firebase 웹 SDK 초기화 위치와 재사용·서버 경계를 설계합니다.
사전 지식: Next.js App Router, Client Component, TypeScript import, 환경변수

웹 SDK 인스턴스를 한 모듈에서 만들고 공유하면 설정과 리전이 흩어지는 것을 줄입니다. 중복 초기화 방지는 현재 JavaScript 실행 환경의 앱 레지스트리 재사용이지 사용자 인증을 서버에 전달하는 기능이 아닙니다.

별도 연습 앱에서 시작하려면 Next.js App Router 첫 프로젝트 만들기의 Next.js App Router 환경을 준비하세요. 이 글은 TaskFlow의 이전 기능을 요구하지 않습니다. 아래 전체 모듈과 확인 페이지 두 파일로 초기화 동작만 확인합니다.

프로젝트 준비

기존 Next.js App Router 프로젝트에서 다음 명령을 실행합니다.

npm install firebase client-only

Firebase Console에서 웹 앱을 등록하고 공개 웹 설정을 .env.local의 NEXT_PUBLIC_FIREBASE_API_KEY, AUTH_DOMAIN, PROJECT_ID, STORAGE_BUCKET, APP_ID에 각각 대응시킵니다. 모든 변수에는 NEXT_PUBLIC_FIREBASE_ 접두사를 붙입니다. 서비스 계정 private key는 이 파일의 공개 변수로 넣지 않습니다.

src/shared/libs/firebase/firebase.ts · 전체 모듈; 기존 Next.js 프로젝트에 적용

import 'client-only';
import { getApp, getApps, initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { getStorage } from 'firebase/storage';
import { getFunctions } from 'firebase/functions';

const firebaseConfig = {
  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,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID
};
for (const [name, value] of Object.entries(firebaseConfig)) {
  if (!value) throw new Error(`Firebase 설정 누락: ${name}`);
}
const app = getApps().some((item) => item.name === '[DEFAULT]')
  ? getApp()
  : initializeApp(firebaseConfig);

export const auth = getAuth(app);
export const db = getFirestore(app);
export const storage = getStorage(app);
export const functions = getFunctions(app, 'us-central1');
export default app;
Next.js firebase.ts client server 경계 구조

client-only와 use client의 역할

client-only는 서버 코드에서 잘못 가져오는 것을 막는 표시입니다. 화면 컴포넌트에는 use client를 쓰고 그 컴포넌트가 이 모듈을 가져오도록 합니다. Admin SDK와 서버 세션 검증은 별도 server-only 모듈에서 다룹니다. 브라우저 currentUser를 서버가 자동으로 공유한다고 생각하면 보호 API가 비게 됩니다.

환경변수 오류를 빨리 드러내기

모듈은 누락된 키 이름만 오류에 포함하고 값 전체는 출력하지 않습니다. 공개 환경변수는 Next.js 빌드 시 브라우저 코드에 포함되므로 배포 설정 변경 후 다시 빌드합니다. dev 서버에서도 .env.local 변경 후 재시작하세요. bucket은 Console의 실제 이름을 그대로 사용하고 Functions 리전은 배포 함수와 일치시킵니다.

Firebase 초기화 중복과 환경변수 확인 체크리스트

Emulator는 별도 연결 선택입니다

이 기본 모듈은 실제 설정의 Firebase 서비스에 연결합니다. Emulator를 사용하려면 최초 서비스 호출 전에 connectAuthEmulator/connectFirestoreEmulator/connectStorageEmulator/connectFunctionsEmulator를 명시적으로 연결해야 합니다. Functions만 로컬로 바꾸어도 Auth·Firestore·Storage가 자동으로 로컬이 되지 않습니다. 예외를 모두 잡아 이미 연결된 것이라고 무시하는 방식은 실제 연결 오류를 숨깁니다.

확인 순서

설정 한 개를 개발 환경에서 비워 오류에 해당 키 이름만 보이는지 확인합니다. 다시 채우고 dev 서버를 재시작해 Client Component에서 인스턴스를 가져옵니다. Fast Refresh 후 duplicate-app 오류가 없는지, production build가 서버 전용 모듈을 섞지 않는지 확인합니다. 앱 초기화 성공은 로그인·DB 읽기·Storage 쓰기 권한 성공을 뜻하지 않습니다.

두 가지 실패를 먼저 확인하기

아래 화면은 개발 중 연결 대상을 확인하기 위한 예시입니다. 기존 src/app/firebase-check/page.tsx가 있다면 다른 경로를 사용하세요. 프로젝트에서 @/ 별칭을 쓰지 않는다면 상대 import 경로로 바꾸세요.

src/app/firebase-check/page.tsx · 개발 중 확인 화면

'use client';
import firebaseApp from '@/shared/libs/firebase/firebase';

export default function FirebaseCheckPage() {
  return <p>연결 대상 프로젝트: {firebaseApp.options.projectId}</p>;
}
  1. .env.local의 NEXT_PUBLIC_FIREBASE_PROJECT_ID를 잠시 비운 뒤 개발 서버를 다시 시작하고 /firebase-check를 엽니다. 오류가 누락된 설정 이름을 가리키는지 확인하고, 값 자체는 기록하지 않습니다.
  2. 원래 값을 복원하고 서버를 재시작합니다. 화면의 projectId를 Firebase Console의 대상 프로젝트 ID와 비교합니다.
  3. npm run build의 종료 결과를 확인합니다. 성공해도 실제 Auth·Firestore·Storage 요청이 허용된다는 뜻은 아닙니다.

기록할 증거는 누락된 키 이름, 화면에 표시된 대상 프로젝트 ID, 빌드 결과입니다. 확인 화면은 진단 후 제거해도 됩니다. 이 예시는 독자가 자신의 프로젝트에서 실행하는 절차이며, 이 글 편집에서는 실제 Next.js 프로젝트 빌드를 실행하지 않았습니다.

직접 확인할 결과

설정 누락 오류에 키 이름이 표시되고, 복원 뒤 표시된 projectId가 의도한 프로젝트와 일치하며, 빌드 결과를 기록했는지 확인합니다. 실제 Next.js 빌드·클라우드 연결은 이 편집 환경에서 실행하지 않았습니다.

검증 범위와 기준일

공식 문서 확인일: 2026-09-13. 웹 SDK 예제는 모듈형 API 기준입니다. 이 글의 코드·구조 정적 검토와 실제 클라우드 인증·저장·배포 검증을 구분합니다. 본인 개발 Firebase 프로젝트의 실제 인증·권한·배포 요청은 이 편집 환경에서 실행하지 않았습니다.

이어서 학습하기

공식 문서

이 글이 도움이 되었나요?

조회 중

읽음 기록

읽음 — / 전체 20개 · 필수 14개

이 글을 쓴 해비

웹사이트를 제작·운영하고, 개인 서비스와 자동화·AI 도구를 만듭니다. 직접 만들며 배운 내용과 문제 해결 과정을 BlogFlow에 기록합니다.

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기