본문 바로가기
TrobleShooting

[Flutter/FCM] ios기기에서 firebaseMessagingBackgroundHandler 호출 오류

by 6cess 2024. 1. 23.

Flutter / FCM 프로젝트 진행 중에 iOS 기기에서 앱이 terminated 되고 첫번째 FCM push를 받을 때 알림이 뜨지 않는 에러가 발생했다.
firebaseMessagingBackgroundHandler 이 호출되어야 그 내부에 notification을 표시하는 로직이 실행되어 알람이 뜨게 된다.
앱 종료 후 첫번째 푸시 때에만 firebaseMessagingBackgroundHandler 호출되지 않는지 원인을 파악해야 한다.
 

1. 주요 레퍼런스 알아보기

가끔은 너무 잦은 발생으로 인해 유명해진 버그들이 있을까 싶어서 먼저 가볍게 구글링해보았다. 
 
레퍼런스들을 찾아보니 FCM 백그라운드에서 메시지 받기 위해 빼먹기 쉬운 설정들에 대한 자료들은 있었어도 첫번째만 안 받아지는 상황에 대한 자료는 찾기 힘들었다. 그래도 일단 유사한 사례들을 찾아보았다.
 
아래는 FCM 백그라운드에서 메시지가 받아지지 않는 증상에 대한 주요 제안들이다.
 
1. iOS는 시뮬레이터가 아닌 실제 기기에서만 작동된다.
2. iOS는 xcode 프로젝트에서 Background Mode 설정에서 Bacground Fetch, Remote Notifications, Bacground Processing을 선택해줘야 한다.
3. APN 키를 생성해서 Firebase console에 등록해야 한다.
4. 사용자에게 권한 요청을 해야 한다.
5. _firebaseMessagingBackgroundHandler 메서드를 문서가 안내하는 방식대로 작성해야 한다.
 
위 제안들은 결국 FCM 문서가 안내 내용 중에 빠드린 것들에 대한 내용이었다. 결국 백그라운드 푸쉬 기능이 아예 발생하지 않는 경우에 대한 제안이었고 첫번째가 발생하지 않는 것에 대한 내용들은 아니다. 아쉽
그래도 모르니 참고하여 빠뜨린 설정이 없는지 체크해봤다.
 
다음으로 좀 더 정확한 문제 파악을 위해 로그를 찬찬히 확인해보기로 했다.
 

2. iOS 기기 xcode로 로그 확인하기

우선 앱 종료 시에 발생하는 로그를 확인해야 하는데 ios 시뮬레이터는 애초에 fcm 푸쉬를 받지 못한다. 또한 기기를 연결해서 xcode로 디버그해보려 했으나 이 또한 앱을 종료할 경우 콘솔 로그 기능도 종료되어 로그를 볼 수가 없었다. 
 
그래서 테스트플라잇에 앱을 배포하여 ios기기에 설치한 후  xcode에 연결하여 로그를 읽어보는 방식으로 진행했다.
 
버그 상황을 reproduce한 후 로그를 확인해보니 APNs 메시지는 실 기기에 수신되고 있었다..!
그리고 앱을 깨우는 작업이 진행되는 로그까지 확인했다.
그런데 첫번째 푸쉬 때에 앱 초기화 작업이 진행되다가 중단되고 두번째 푸시 도착 시 나머지 초기화 작업을 완료하는 것으로 로그가 확인되었다. 이는 ios가 백그라운드 작업에 리소스 제한을 두기 때문인 것 같다.
 
그렇다면 firebaseMessagingBackgroundHandler가 호출이 안되는 원인이 리소스 제한으로 인해 firebaseMessagingBackgroundHandler 호출되기 전에 백그라운드 작업이 중단되어서 그런 것일까?

 

3. 앱 초기화 작업 최소화

그래서 앱 초기화 작업을 첫번째 푸시로 허용되는 리소스 내에 마무리될 수 있도록 백그라운드 상황과 포어그라운드 상황에서의 앱 초기화 작업을 구분하여 최소화했다. 그리고 앱이 끝까지 초기화되는 것을 확인하고 테스트해보았지만 여전히 첫 푸쉬에서는 firebaseMessagingBackgroundHandler가 호출되지 않았다.
 

4. 핸들러 등록 메서드를 초기화 앞순서로 이동

좌절 후 다시 구글링을 하다 나와 동일한 사례를 찾게 되었다.
https://github.com/firebase/flutterfire/issues/11500 

[firebase_messaging]: After the app is terminated/swiped away, onBackgroundMessage only fires after a second notification on iOS

Is there an existing issue for this? I have searched the existing issues. Are you aware of the differences between iOS and Android background message handling? I understand that iOS and Android bac...

github.com

 
 
핵심은 firebaseMessagingBackgroundHandler 등록을 main메서드에서 충분히 앞부분에 배치하라는 제안이었다.

Future<void> main() async {

  // [Firebase] FirebaseMessaging 백그라운드 메시지를 받기 위해 리스너를 활성화 합니다.
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  
  ,,,
  
}

 
그러니 첫번째 푸시가 온다....
 
앱 초기화하는 작업과 백그라운드핸들러가 호출되는 작업이 따로 실행되어 백그라운드핸들러 등록을 미리 해놓지 않으면 앱 초기화 중간에 백그라운드 핸들러를 호출할 수 없어서 발생하는 문제 같다.
 
미리 삽질하신 분께 고개 숙여 감사를....