Firebase JS SDK 또는 다른 Firebase 클라이언트 SDK를 사용해 본 적이 있다면 FirebaseApp
인터페이스와 이를 사용하여 앱 인스턴스를 구성하는 방법을 잘 알고 있을 것입니다. 서버 측에서 유사한 작업을 용이하게 하기 위해 Firebase는 FirebaseServerApp
을 제공합니다.
FirebaseServerApp
은 서버 측 렌더링(SSR) 환경에서 사용하기 위한 FirebaseApp
의 변형입니다. 클라이언트 측 렌더링(CSR)/서버 측 렌더링 구분을 넘나드는 Firebase 세션을 계속하는 도구가 포함되어 있습니다. 이러한 도구와 전략을 사용하면 Firebase로 빌드되고 Firebase App Hosting과 같은 Google 환경에 배포된 동적 웹 앱을 개선하는 데 도움이 됩니다.
FirebaseServerApp
를 사용하여 다음을 수행합니다.
- 전체 관리 권한이 있는 Firebase Admin SDK와 달리 사용자 컨텍스트 내에서 서버 측 코드를 실행합니다.
- SSR 환경에서 앱 체크 사용을 사용 설정합니다.
- 클라이언트에서 생성된 Firebase 인증 세션을 계속합니다.
FirebaseServerApp 수명 주기
서버 측 렌더링(SSR) 프레임워크 및 클라우드 작업자와 같은 브라우저가 아닌 기타 런타임은 여러 실행에서 리소스를 재사용하여 초기화 시간을 최적화합니다. FirebaseServerApp
은 참조 수 메커니즘을 사용하여 이러한 환경을 수용하도록 설계되었습니다. 앱이 이전 initializeServerApp
과 동일한 파라미터를 사용하여 initializeServerApp
을 호출하면 이미 초기화된 동일한 FirebaseServerApp
인스턴스를 수신합니다. 이렇게 하면 불필요한 초기화 오버헤드와 메모리 할당이 줄어듭니다. FirebaseServerApp
인스턴스에서 deleteApp
이 호출되면 참조 수가 감소하고 참조 수가 0이 되면 인스턴스가 해제됩니다.
FirebaseServerApp
인스턴스 삭제
특히 여러 비동기 작업을 동시에 실행하는 경우 FirebaseServerApp
인스턴스에서 deleteApp
을 호출해야 하는 시점을 파악하기가 쉽지 않을 수 있습니다. FirebaseServerAppSettings
의 releaseOnDeref
필드를 사용하면 이를 간소화할 수 있습니다. releaseOnDeref
에 요청 범위의 수명이 있는 객체 참조(예: SSR 요청의 헤더 객체)를 할당하면 프레임워크가 헤더 객체를 회수할 때 FirebaseServerApp
의 참조 수가 줄어듭니다. 이렇게 하면 FirebaseServerApp
인스턴스가 자동으로 정리됩니다.
다음은 releaseOnDeref
사용 예시입니다.
/// Next.js
import { headers } from 'next/headers'
import { FirebaseServerAppSettings, initializeServerApp} from "@firebase/app";
export default async function Page() {
const headersObj = await headers();
appSettings.releaseOnDeref = headersObj;
let appSettings: FirebaseServerAppSettings = {};
const serverApp = initializeServerApp(firebaseConfig, appSettings);
...
}
클라이언트에서 생성된 인증된 세션 재개
FirebaseServerApp
인스턴스가 인증 ID 토큰으로 초기화되면 클라이언트 측 렌더링(CSR)과 서버 측 렌더링(SSR) 환경 간에 인증된 사용자 세션을 연결할 수 있습니다. 인증 ID 토큰이 포함된 FirebaseServerApp
객체로 초기화된 Firebase 인증 SDK 인스턴스는 애플리케이션에서 로그인 메서드를 호출하지 않아도 초기화 시 사용자를 로그인하려고 시도합니다.
인증 ID 토큰을 제공하면 앱이 클라이언트에서 인증의 로그인 메서드를 사용할 수 있으므로 사용자 상호작용이 필요한 로그인 메서드에서도 서버 측에서 세션이 계속됩니다. 또한 인증된 Firestore 쿼리와 같은 집약적인 작업을 서버로 오프로드할 수 있으므로 앱의 렌더링 성능이 개선됩니다.
/// Next.js
import { initializeServerApp } from "firebase/app";
import { getAuth } from "firebase/auth";
// Replace the following with your app's
// Firebase project configuration
const firebaseConfig = {
// ...
};
const firebaseServerAppSettings = {
authIdToken: token // See "Pass client tokens to the server side
// rendering phase" for an example on how transmit
// the token from the client and the server.
}
const serverApp =
initializeServerApp(firebaseConfig,
firebaseServerAppSettings);
const serverAuth = getAuth(serverApp);
// FirebaseServerApp and Auth will now attempt
// to sign in the current user based on provided
// authIdToken.
SSR 환경에서 앱 체크 사용
앱 체크 적용은 Firebase SDK가 내부적으로 getToken
을 호출하는 데 사용하는 앱 체크 SDK 인스턴스를 사용합니다. 그러면 결과 토큰이 모든 Firebase 서비스에 대한 요청에 포함되어 백엔드에서 앱을 검증할 수 있습니다.
그러나 앱 체크 SDK는 앱 유효성 검사를 위한 특정 휴리스틱에 액세스하는 데 브라우저가 필요하므로 서버 환경에서는 초기화할 수 없습니다.
FirebaseServerApp
은 대안을 제공합니다. FirebaseServerApp
초기화 중에 클라이언트에서 생성한 앱 체크 토큰이 제공되면 Firebase 제품 SDK에서 Firebase 서비스를 호출할 때 이를 사용하게 되므로 앱 체크 SDK 인스턴스가 필요하지 않습니다.
/// Next.js
import { initializeServerApp } from "firebase/app";
// Replace the following with your app's
// Firebase project configuration
const firebaseConfig = {
// ...
};
const firebaseServerAppSettings = {
appCheckToken: token // See "Pass client tokens to the server side
// rendering phase" for an example on how transmit
// the token from the client and the server.
}
const serverApp =
initializeServerApp(firebaseConfig,
firebaseServerAppSettings);
// The App Check token will now be appended to all Firebase service requests.
클라이언트 토큰을 서버 측 렌더링 단계에 전달
인증된 인증 ID 토큰(및 앱 체크 토큰)을 클라이언트에서 서버 측 렌더링(SSR) 단계로 전송하려면 서비스 워커를 사용하세요. 이 접근 방식에서는 SSR을 트리거하는 가져오기 요청을 가로채고 요청 헤더에 토큰을 추가합니다.
Firebase 인증 서비스 워커의 참조 구현은 서비스 워커를 사용한 세션 관리를 참고하세요. FirebaseServerApp
초기화에 사용할 헤더에서 이러한 토큰을 파싱하는 방법을 보여주는 코드는 서버 측 변경사항을 참고하세요.