Flutter Firebase Messaging (포그라운드 / 백그라운드 / 종료) 모두
삽질을 일주일 정도 하고 정리한 글입니다 ㅜ.ㅜ 도움이 되시면 좋겠습니다.
firebase configure가 이미 되어있는 전제 하에 설명하는 글이다!
이것이 안되어있다면 여기서 간단하고 빠르게 수행하고 이 글을 다시 보면 된다!
우선 pubspec.yaml 파일에 두가지 dependency를 추가한다.
firebase_messaging: ^13.1.0
flutter_local_notifications: ^12.0.4
firebase_messaging은 말그대로 fcm을 위한 것이고
flutter_local_notification은 특수 경우 처리를 위한 것이다.
FCM은 앱이 백그라운드 / 종료 상태에서 정상적으로 notification 알림 팝업이 동작한다.
하지만 앱이 포그라운드 상태일 경우에 notification 알림 팝업이 동작하지 않는다.
따라서 이를 띄워주기 위해서 flutter_local_notification을 이용한다.
Android -> app -> src -> main -> AndroidManifest
<Application> 태그 안에 아래 코드를 추가한다.
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel"/>
flutter의 메인함수를 다음과 같이 구상한다.
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel',
'High Importance Notifications',
description: 'This channel is used for important notifications.',
importance: Importance.max,
);
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging messaging = FirebaseMessaging.instance;
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true, // Required to display a heads up notification
badge: true,
sound: true,
);
androidNotiSet();
print('User granted permission: ${settings.authorizationStatus}');
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('high_importance_channel', 'High Importance Notifications',
channelDescription: 'This channel is used for important notifications.',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
const NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
await flutterLocalNotificationsPlugin.show(
0, '${message.notification!.title}', '${message.notification!.body}', notificationDetails,
payload: 'item x');
});
runApp(const MyApp());
}
여기서 나온 _firebaseMessagingBackgroundHandler 과, androidNotiSet 은 아래에 함수로 코드를 작성한다.
Future<void> androidNotiSet() async {
if(Platform.isAndroid) {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()!.requestPermission();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
}
const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
final DarwinInitializationSettings initializationSettingsIOS = const DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
print("Handling a background message: ${message.messageId}");
}
하나 세팅해야 할 것이 있다.
Android -> app -> src -> main -> res -> drawable 안에 app_icon.png의 임의의 아이콘을 추가해야 한다!
그리고 하나 자세히 설명하자면.. 위 코드 중에
FirebaseMessaging.onMessage.listen
이것은 포그라운드에서 FCM을 받았을 때 어떻게 처리할지에 대한 로직이다.
기본적으로 FCM은 백그라운드/Terminated에서 도착 시 FCM 메세지가 온 그대로 전달되어 팝업되는데
포그라운드에서 FCM을 받을 시 팝업되지 않는다. 따라서 Flutter_loca_notification을 이용해서 이 함수 안에서 커스텀으로 띄워야한다.
메세지 또한 커스텀 할 수 있고, FCM에서 온 데이터를 그대로 전달받아 사용할 수도 있다.
+ firebase_analytics는 FCM 필수 적용사항이 아니다.
+ FingerPrint는 적용하지 않아도 동작한다. FingerPrint는 Auth같은 로그인에서 필요.
+ 오류가 날 경우 pubspec.yaml에 다음을 추가한다
firebase_core_platform_interface: 4.5.1
참고
https://hevton.tistory.com/707