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 등) 호출이 정상적으로 이루어지지 않음
- 흰 화면 상태에서 앱이 멈추거나, 통신 실패와 관련된 에러 로그 출력
문제 원인 분석
- localhost와 127.0.0.1의 차이
- iOS 시뮬레이터는 localhost를 호스트로 사용할 경우, 실제 머신(Host Machine)이 아닌 시뮬레이터 자체를 참조.
- 따라서 Firebase Emulator가 실제 머신에서 실행되고 있는 경우, iOS 시뮬레이터는 이를 인식하지 못하고 통신 실패.
- 환경 변수 설정 문제
- .env.development 파일에서 FIREBASE_EMULATOR_HOST 값이 localhost로 설정되어 있음.
- 이로 인해 앱 내 Firebase Emulator 초기화 코드에서 잘못된 호스트 값을 참조.
- 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 기능 호출 성공.
배운 점
- localhost와 127.0.0.1의 차이
- iOS 시뮬레이터에서 localhost가 호스트 머신이 아닌 시뮬레이터 자체를 참조한다는 점을 이해.
- 이를 해결하기 위해 127.0.0.1 사용.
- 환경 변수 관리
- Firebase Emulator와 같은 개발 도구에서 필요한 환경 변수를 명확히 정의하고 검증하는 것이 중요.
- Firebase Emulator 초기화 코드 작성
- 초기화 코드에서 환경 변수의 기본값을 설정하거나 명확히 정의함으로써 디버깅 시간을 단축 가능.
개선 방향
- 환경 변수 자동 검증 도구 작성: 빌드 전에 환경 변수 설정 누락 여부를 검증하는 스크립트 작성.
- Firebase Emulator 설정 가이드 문서화: 팀원과 공유할 수 있는 설정 가이드를 작성하여 반복적인 문제를 예방.
- 시뮬레이터-에뮬레이터 통신 테스트 자동화: iOS 시뮬레이터와 Firebase Emulator 간의 통신 테스트를 자동화하여 문제를 조기에 발견.