firebase_messaging: ^11.2.5
flutter_local_notifications: ^9.2.0
<manifest
...
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<application
...
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
<activity
android:name=".MainActivity"
...
android:showWhenLocked="true"
android:turnScreenOn="true"
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
>
dependencies {
implementation platform('com.google.firebase:firebase-bom:29.0.2')
implementation 'com.google.firebase:firebase-analytics'
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.google.gms:google-services:4.3.10'
}
자세한건 공식 문서 를 참고해주세요.
실행에 앞서 firebase_messaging 공식문서를 통해 몇가지 알아야 할 정보가 있다.
1. ios 시뮬레이터에서는 작동하지 않으며 실기기가 필요하다.
2. 애플리케이션이 foreground 에 있는 경우 Firebase Android SDK는 설정된 알림 채널에 관계없이 FCM 알림 표시를 차단한다고 한다. 따라서 foreground 메시지를 처리하려면 onMessage 로 들어오는 메시지를 처리하고 flutter_local_notifications 으로 로컬 알림을 만들 수 있다.
3. background 메시지 관련 함수는 익명 함수가 아니어야 하고, 최상위에 위치하여야 한다.
( Cloud Messaging, Notifications 공식 문서 참고 )
- 저는 Android, ios 둘 다 실기기로 테스트 진행했습니다.
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Handling a background message ${message.messageId}');
}
late AndroidNotificationChannel channel;
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.high,
);
var initialzationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
var initialzationSettingsIOS = IOSInitializationSettings(
requestSoundPermission: true,
requestBadgePermission: true,
requestAlertPermission: true,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
var initializationSettings = InitializationSettings(
android: initialzationSettingsAndroid, iOS: initialzationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
runApp(const MyApp());
}
class ...
@override
void initState() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
var androidNotiDetails = AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
);
var iOSNotiDetails = const IOSNotificationDetails();
var details =
NotificationDetails(android: androidNotiDetails, iOS: iOSNotiDetails);
if (notification != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
details,
);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
print(message);
});
super.initState();
}
token = await FirebaseMessaging.instance.getToken();
print("token : ${token ?? 'token NULL!'}");
FCM 구현 예제를 찾고 있었는데 좋은 글 아주 감사합니다.
게시글 참고해서 OnMessage와 백그라운드까지는 구현 완료하였습니다.
하지만 앱이 종료되있는 상태에서 푸시 알림은 실행되지 않습니다.
혹시 조언 좀 구할 수 있을까요?
좋은글 감사합니다!
한가지 질문이있습니다. 작성해주신 코드 그대로 사용하였는데요.
iOS 에서 앱이 켜져있는 상태에서는 헤드업 노티(?) 가 2번 오고있어서요
해당부분은 어떻게 제어해줘야할까요?
감사합니다~!