Cloud Firestore 에뮬레이터에 앱 연결

앱을 Cloud Firestore 에뮬레이터에 연결하기 전에 전체 Firebase 로컬 에뮬레이터 도구 모음 워크플로를 이해하고 로컬 에뮬레이터 도구 모음을 설치 및 구성하며 CLI 명령어를 검토해야 합니다.

Firebase 프로젝트 선택

Firebase 로컬 에뮬레이터 도구 모음은 단일 Firebase 프로젝트의 제품을 에뮬레이션합니다.

에뮬레이터를 시작하기 전에 사용할 프로젝트를 선택하려면 CLI로 작업 디렉터리에서 firebase use를 실행합니다. 또는 --project 플래그를 각 에뮬레이터 명령어에 전달합니다.

로컬 에뮬레이터 도구 모음은 실제 Firebase 프로젝트 및 데모 프로젝트의 에뮬레이션을 지원합니다.

프로젝트 유형 특징 에뮬레이터와 함께 사용
실제

실제 Firebase 프로젝트는 주로 Firebase Console을 통해 만들고 구성한 프로젝트입니다.

실제 프로젝트에는 데이터베이스 인스턴스, 스토리지 버킷, 함수 또는 해당 Firebase 프로젝트에 설정한 기타 리소스와 같은 라이브 리소스가 있습니다.

실제 Firebase 프로젝트로 작업할 때는 지원되는 제품 일부 또는 전부를 에뮬레이션할 수 있습니다.

에뮬레이션하지 않는 제품의 경우 앱과 코드가 데이터베이스 인스턴스, 스토리지 버킷, 함수 등 라이브 리소스와 상호작용합니다.

데모

데모 Firebase 프로젝트에는 실제 Firebase 구성이 없으며 라이브 리소스도 없습니다. 이러한 프로젝트는 일반적으로 Codelab 또는 기타 튜토리얼을 통해 액세스합니다.

데모 프로젝트의 프로젝트 ID에는 demo- 프리픽스가 있습니다.

데모 Firebase 프로젝트로 작업할 때는 앱과 코드가 에뮬레이터와 상호작용합니다. 앱이 에뮬레이터에서 실행 중이지 않은 리소스와 상호작용하려고 하면 코드가 실패합니다.

가능한 한 데모 프로젝트를 사용하는 것이 좋습니다. 장점은 다음과 같습니다.

  • 손쉬운 설정: Firebase 프로젝트를 만들지 않고도 에뮬레이터를 실행할 수 있습니다.
  • 강력한 안전성: 코드에서 실수로 에뮬레이션되지 않은(프로덕션) 리소스를 호출하더라도 데이터 변경, 사용, 청구 등이 발생할 가능성이 없습니다.
  • 오프라인 지원 향상: SDK 구성을 다운로드하기 위해 인터넷에 액세스할 필요가 없습니다.

에뮬레이터와 통신하도록 앱 구현

시작 시 Cloud Firestore 에뮬레이터는 firebase.json 파일의 각 firestore 구성에 대해 기본 데이터베이스와 이름이 지정된 데이터베이스를 만듭니다. firebase.json 파일을 사용하여 Cloud Firestore 보안 규칙을 이름이 지정된 데이터베이스에 명시적으로 할당합니다.

이름이 지정된 데이터베이스는 특정 데이터베이스를 참조하는 에뮬레이터에 대한 SDK 또는 REST API 호출에 대한 응답으로 암시적으로 생성됩니다. 이렇게 암시적으로 생성된 데이터베이스는 공개 규칙으로 작동합니다.

현재 에뮬레이터 도구 모음 UI는 기본 데이터베이스를 사용한 대화형 작업을 지원합니다.

Android, Apple 플랫폼, 웹 SDK

Cloud Firestore와 상호작용하도록 인앱 구성 또는 테스트 클래스를 다음과 같이 설정합니다. 다음 샘플에서는 앱 코드가 기본 프로젝트 데이터베이스에 연결됩니다. 기본 데이터베이스 외의 추가 Cloud Firestore 데이터베이스를 사용하는 예시는 여러 데이터베이스 가이드를 참조하세요.

Kotlin+KTX
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
val firestore = Firebase.firestore
firestore.useEmulator("10.0.2.2", 8080)

firestore.firestoreSettings = firestoreSettings {
    isPersistenceEnabled = false
}
Java
// 10.0.2.2 is the special IP address to connect to the 'localhost' of
// the host computer from an Android emulator.
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
firestore.useEmulator("10.0.2.2", 8080);

FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(false)
        .build();
firestore.setFirestoreSettings(settings);
Swift
let settings = Firestore.firestore().settings
settings.host = "127.0.0.1:8080"
settings.cacheSettings = MemoryCacheSettings()
settings.isSSLEnabled = false
Firestore.firestore().settings = settings

웹 모듈식 API

import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";

// firebaseApps previously initialized using initializeApp()
const db = getFirestore();
connectFirestoreEmulator(db, '127.0.0.1', 8080);

웹 네임스페이스화된 API

// Firebase previously initialized using firebase.initializeApp().
var db = firebase.firestore();
if (location.hostname === "localhost") {
  db.useEmulator("127.0.0.1", 8080);
}

에뮬레이터를 사용하여 Firestore 이벤트에 의해 트리거되는 Cloud Functions를 테스트할 때는 추가 설정이 필요하지 않습니다. Firestore와 Cloud Functions 에뮬레이터가 모두 실행되면 자동으로 함께 작동합니다.

Admin SDK

FIRESTORE_EMULATOR_HOST 환경 변수가 설정되면 Firebase Admin SDK가 자동으로 Cloud Firestore 에뮬레이터에 연결됩니다.

export FIRESTORE_EMULATOR_HOST="127.0.0.1:8080"

코드가 Cloud Functions 에뮬레이터 내에서 실행 중인 경우 initializeApp을 호출하면 프로젝트 ID 및 기타 구성이 자동으로 설정됩니다.

Admin SDK 코드를 다른 환경에서 실행되는 공유 에뮬레이터에 연결하려면 Firebase CLI를 사용하여 설정한 것과 동일한 프로젝트 ID를 지정해야 합니다. 프로젝트 ID를 initializeApp에 직접 전달하거나 GCLOUD_PROJECT 환경 변수를 설정할 수 있습니다.

Node.js Admin SDK
admin.initializeApp({ projectId: "your-project-id" });
환경 변수
export GCLOUD_PROJECT="your-project-id"

테스트 간 데이터베이스 삭제

프로덕션 Firestore는 데이터베이스를 삭제하기 위한 플랫폼 SDK 메서드를 제공하지 않지만, Firestore 에뮬레이터는 데이터베이스 삭제를 위해 특별히 REST 엔드포인트를 제공합니다. 이 엔드포인트는 테스트 프레임워크 설정/해제 단계, 테스트 시작 전 테스트 클래스 또는 셸(예: curl 사용)에서 호출할 수 있습니다. 에뮬레이터 프로세스를 종료하는 대신 이 방법을 사용할 수 있습니다.

적절한 메서드에서 다음 엔드포인트에 Firebase 프로젝트 ID(예: firestore-emulator-example)를 제공하여 HTTP DELETE 작업을 수행합니다.

"http://localhost:8080/emulator/v1/projects/firestore-emulator-example/databases/(default)/documents"

당연히 코드는 삭제가 완료되거나 실패했다는 REST 확인을 기다려야 합니다.

셸에서 이 작업을 수행할 수 있습니다.

// Shell alternative…
$ curl -v -X DELETE "http://localhost:8080/emulator/v1/projects/firestore-emulator-example/databases/(default)/documents"

이와 같은 단계를 구현하면 실행 간에 이전 데이터가 삭제되고 새로운 기준 테스트 구성을 사용한다는 확신을 가지고 테스트 순서를 지정하고 함수를 트리거할 수 있습니다.

데이터 가져오기 및 내보내기

데이터베이스 에뮬레이터와 Firebase용 Cloud Storage 에뮬레이터를 사용하면 실행 중인 에뮬레이터 인스턴스에서 데이터를 내보낼 수 있습니다. 단위 테스트 또는 지속적 통합 워크플로에 사용할 기준 데이터 세트를 정의한 다음 내보내기하여 팀과 공유할 수 있습니다.

firebase emulators:export ./dir

테스트에서 에뮬레이터 시작 시 기준 데이터를 가져옵니다.

firebase emulators:start --import=./dir

내보내기 경로를 지정하거나 --import 플래그에 전달된 경로를 사용하여 종료 시 에뮬레이터가 데이터를 내보내도록 지시할 수 있습니다.

firebase emulators:start --import=./dir --export-on-exit

이러한 데이터 가져오기 및 내보내기 옵션은 firebase emulators:exec 명령어에서도 작동합니다. 자세한 내용은 에뮬레이터 명령어 참조를 확인하세요.

보안 규칙 활동 시각화

프로토타입과 테스트 루프를 진행하면서 로컬 에뮬레이터 도구 모음에서 제공하는 시각화 도구와 보고서를 사용할 수 있습니다.

요청 모니터 사용

Cloud Firestore 에뮬레이터를 사용하면 에뮬레이터 도구 모음 UI에서 Firebase 보안 규칙에 대한 평가 추적을 포함한 클라이언트 요청을 시각화할 수 있습니다.

Firestore > 요청 탭을 열어 각 요청의 자세한 평가 순서를 확인합니다.

보안 규칙 평가를 보여주는 Firestore 에뮬레이터 요청 모니터

규칙 평가 보고서 시각화

프로토타입에 보안 규칙을 추가하면 로컬 에뮬레이터 도구 모음 디버그 도구를 사용하여 디버깅할 수 있습니다.

일련의 테스트를 실행한 후 각 보안 규칙이 판정된 방식을 보여주는 테스트 범위 보고서에 액세스할 수 있습니다.

이 보고서를 가져오려면 실행 중 에뮬레이터에서 노출된 엔드포인트를 쿼리하세요. 브라우저 버전에서는 다음 URL을 사용하세요.

http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html

이렇게 하면 규칙이 표현식과 하위 표현식으로 구분되며, 마우스 오버하면 평가 횟수 및 반환된 값을 비롯한 자세한 정보를 얻을 수 있습니다. 이 데이터의 원시 JSON 버전에서는 쿼리에 다음 URL을 포함하세요.

http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage

여기서 HTML 버전의 보고서는 정의되지 않은 값과 null 값 오류를 발생시키는 평가를 보여줍니다.

Cloud Firestore 에뮬레이터와 프로덕션 환경의 차이점

Cloud Firestore 에뮬레이터에서는 프로덕션 서비스의 동작을 충실하게 복제하려고 하지만 몇 가지 주요 제한사항이 있습니다.

Cloud Firestore의 여러 데이터베이스 지원

현재 에뮬레이터 도구 모음 UI는 기본 데이터베이스의 대화형 생성, 수정, 삭제, 요청 모니터링, 보안 시각화를 지원하지만 이름이 지정된 추가 데이터베이스는 지원하지 않습니다.

그러나 에뮬레이터 자체는 firebase.json 파일의 구성을 기반으로 SDK 또는 REST API 호출에 대한 응답으로 암시적으로 이름이 지정된 데이터베이스를 만듭니다.

거래

에뮬레이터는 현재 프로덕션 환경에 보이는 모든 트랜잭션 동작을 구현하지는 않습니다. 한 문서에 여러 번의 동시 쓰기를 수반하는 기능을 테스트하는 경우 에뮬레이터에서 쓰기 요청을 완료하는 속도가 느릴 수 있습니다. 경우에 따라 잠금이 해제되는 데 최대 30초가 걸릴 수 있습니다. 필요한 경우 테스트 시간 제한을 조정해 보세요.

색인

에뮬레이터는 복합 색인을 추적하지 않으며 대신 유효한 쿼리를 실행합니다. 실제 Cloud Firestore 인스턴스에서 앱을 테스트하여 필요한 색인을 파악해야 합니다.

한도

에뮬레이터는 프로덕션에서 시행되는 모든 한도를 적용하지 않습니다. 예를 들어 프로덕션 서비스에서는 너무 커서 거부될 트랜잭션을 에뮬레이터는 허용할 수 있습니다. 문서화된 한도를 숙지하고 이러한 문제를 사전에 방지하도록 앱을 설계해야 합니다.

다음 단계