dev/flutter
flutter - 백그라운드 푸시 메세지 클릭 이벤트
wlrn566
2023. 7. 10. 13:51
백그라운드에서 푸시 알람이 왔을 때 해당 알람을 클릭하면 앱이 켜지게 된다.
하지만 알람의 종류나 내용에 따라 메인화면이 아닌 지정된 화면이 나와야 할 때가 있다.
공식 예제를 보면 onMessageOpenedApp()를 사용하면 된다고 한다.
1. 푸시 알람 이벤트 코드 추가
플러터에서 화면 전환등을 할 때 context가 필요하다.
그런데 푸시 알람을 클릭했을 때는 차근차근 위젯트리를 밟고 가는 것이 아니라 바로 어떤 페이지로 전환을 시킨다.
그러기 위해 context없이 navigatorKey를 이용하여야 한다.
// 백그라운드 수신
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
log("백그라운드에서 푸시 클릭");
if(message.data['id'] == '1') {
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.of(GlobalVariable.navigatorKey.currentContext!) // navigatorKey사용
.push(MaterialPageRoute(
builder: (context) => FirstPage()));
});
return;
}
});
2. navigatorKey 선언
// GlobalKey 만들기
class GlobalVariable {
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
}
// main.dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: GlobalVariable.navigatorKey, // context 없이 라우팅을 위함
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyWidget()
);
}
}
import 'dart:developer';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_notification/first.dart';
import 'package:flutter_notification/global.dart';
import 'package:flutter_notification/second.dart';
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
// await Firebase.initializeApp();
// print("Handling a background message: ${message.messageId}");
log("background message data: ${message.data}");
}
Future<void> setNotification() async {
// 채널 생성
var channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // name
description: 'This channel is used for important notifications.', // description
importance: Importance.high,
);
var flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
// 포그라운드 메세지 수신
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// print('Got a message whilst in the foreground!');
log('forground message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
// 포그라운드에서 푸시 알람 클릭 시
// if (message.data['id'] == '1') {
// Navigator.of(GlobalVariable.navigatorKey.currentContext!)
// .push(MaterialPageRoute(
// builder: (context) => SecondPage()));
// }
flutterLocalNotificationsPlugin.show(
message.hashCode,
message.notification?.title,
message.notification?.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: '@mipmap/ic_launcher',
),
iOS: const DarwinNotificationDetails(
badgeNumber: 1,
subtitle: 'subtitle',
sound: 'slow_spring_board.aiff',
)
)
);
}
});
// 백그라운드 수신
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
log("백그라운드에서 수신");
if(message.data['id'] == '1') {
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.of(GlobalVariable.navigatorKey.currentContext!)
.push(MaterialPageRoute(
builder: (context) => FirstPage()));
});
return;
}
});
}