Coding/개발

iOS 시뮬레이터와 Firebase Emulator 간의 통신 문제 해결 보고서

_Woo_ 2025. 1. 13. 20:47

문제 상황

Flutter 프로젝트에서 Firebase Emulator를 활용한 개발 환경을 설정하는 중, iOS 시뮬레이터에서 Firebase Emulator와의 통신 문제로 인해 다음과 같은 상황이 발생:

  • iOS 시뮬레이터에서 localhost를 사용하여 Firebase Emulator와 통신 시 연결 실패
  • 앱 실행 시 Firebase Emulator 설정이 제대로 적용되지 않아 Firebase 기능(Firestore, Functions, Storage 등) 호출이 정상적으로 이루어지지 않음
  • 흰 화면 상태에서 앱이 멈추거나, 통신 실패와 관련된 에러 로그 출력

 

문제 원인 분석

  1. localhost와 127.0.0.1의 차이
    • iOS 시뮬레이터는 localhost를 호스트로 사용할 경우, 실제 머신(Host Machine)이 아닌 시뮬레이터 자체를 참조.
    • 따라서 Firebase Emulator가 실제 머신에서 실행되고 있는 경우, iOS 시뮬레이터는 이를 인식하지 못하고 통신 실패.
  2. 환경 변수 설정 문제
    • .env.development 파일에서 FIREBASE_EMULATOR_HOST 값이 localhost로 설정되어 있음.
    • 이로 인해 앱 내 Firebase Emulator 초기화 코드에서 잘못된 호스트 값을 참조.
  3. Firebase Emulator 초기화 코드의 기본값 미설정
    • FirebaseFunctions 및 FirebaseStorage의 초기화 과정에서 기본값으로 localhost가 사용됨.
    • iOS 시뮬레이터에서 이 기본값을 변경하지 않으면 통신 문제가 발생.

문제 해결 과정

1. FIREBASE_EMULATOR_HOST 값 수정

.env.development 파일에서 FIREBASE_EMULATOR_HOST 값을 127.0.0.1로 변경:

 

FIREBASE_EMULATOR_HOST=127.0.0.1

 

  • 127.0.0.1은 호스트 머신을 참조하며, iOS 시뮬레이터에서도 이를 올바르게 인식할 수 있음.

2. Firebase Emulator 초기화 코드 수정

main.dart 파일의 Firebase Emulator 초기화 코드에서 localhost를 사용하던 부분을 FIREBASE_EMULATOR_HOST 값으로 대체:

 

FirebaseFirestore.instance.settings = Settings(
  host: '${dotenv.env['FIREBASE_EMULATOR_HOST']}:${dotenv.env['FIREBASE_FIRESTORE_PORT'] ?? '8080'}',
  sslEnabled: false,
  persistenceEnabled: false,
);

FirebaseFunctions.instance.useFunctionsEmulator(
  dotenv.env['FIREBASE_EMULATOR_HOST'] ?? '127.0.0.1',
  int.parse(dotenv.env['FIREBASE_FUNCTIONS_PORT'] ?? '5001'),
);

FirebaseStorage.instance.useStorageEmulator(
  dotenv.env['FIREBASE_EMULATOR_HOST'] ?? '127.0.0.1',
  int.parse(dotenv.env['FIREBASE_STORAGE_PORT'] ?? '9199'),
);

 

  • dotenv.env['FIREBASE_EMULATOR_HOST']를 활용하여 환경 변수에 정의된 호스트 값을 동적으로 참조.
  • 기본값으로 127.0.0.1 설정.

3. 환경 변수 검증 코드 강화

환경 변수 검증 단계에서 FIREBASE_EMULATOR_HOST 값이 비어있지 않은지 확인:

 

final requiredEnvVars = [
  'FIREBASE_ENV',
  'USE_FIREBASE_EMULATOR',
  'FIREBASE_EMULATOR_HOST',
  'FIREBASE_FIRESTORE_PORT',
  'FIREBASE_FUNCTIONS_PORT',
  'FIREBASE_STORAGE_PORT',
];

for (final envVar in requiredEnvVars) {
  if (dotenv.env[envVar]?.isEmpty ?? true) {
    throw Exception('⚠️ Required environment variable $envVar is not set');
  }
}

 

4. Firebase Emulator 실행

Firebase Emulator를 실행할 때 아래 명령어로 Firebase Emulator Suite를 올바르게 실행:

 

firebase emulators:start --only functions,firestore,storage

 

Firebase Emulator가 로컬 호스트(127.0.0.1)에서 실행되도록 설정.

 

5. iOS 시뮬레이터에서 앱 실행

Flutter 앱을 실행할 때 flutter run 명령어를 활용하여 iOS 시뮬레이터에서 앱을 실행.
환경 변수를 전달하여 Firebase Emulator 설정이 적용되도록 함:

 

flutter run --dart-define=ENV=development

 

결과

  • iOS 시뮬레이터와 Firebase Emulator 간의 통신 문제 해결.
  • 앱이 정상적으로 Firebase Emulator와 통신하며, Firestore, Functions, Storage 기능 호출 성공.

배운 점

  1. localhost와 127.0.0.1의 차이
    • iOS 시뮬레이터에서 localhost가 호스트 머신이 아닌 시뮬레이터 자체를 참조한다는 점을 이해.
    • 이를 해결하기 위해 127.0.0.1 사용.
  2. 환경 변수 관리
    • Firebase Emulator와 같은 개발 도구에서 필요한 환경 변수를 명확히 정의하고 검증하는 것이 중요.
  3. Firebase Emulator 초기화 코드 작성
    • 초기화 코드에서 환경 변수의 기본값을 설정하거나 명확히 정의함으로써 디버깅 시간을 단축 가능.

개선 방향

  • 환경 변수 자동 검증 도구 작성: 빌드 전에 환경 변수 설정 누락 여부를 검증하는 스크립트 작성.
  • Firebase Emulator 설정 가이드 문서화: 팀원과 공유할 수 있는 설정 가이드를 작성하여 반복적인 문제를 예방.
  • 시뮬레이터-에뮬레이터 통신 테스트 자동화: iOS 시뮬레이터와 Firebase Emulator 간의 통신 테스트를 자동화하여 문제를 조기에 발견.