How to handle notification payload. My app is that when killing the app, you always have to log in again. When receiving notification -> click on notification -> route to logIn screen -> after logging in, it will route to the Home screen. Here I am handling it in onReady().
const _initSettings = InitializationSettings(
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
iOS: DarwinInitializationSettings(),
);
const _notificationDetails = NotificationDetails(
android: AndroidNotificationDetails(
'channel id',
'channel name',
icon: '@mipmap/ic_launcher',
importance: Importance.max,
styleInformation: BigTextStyleInformation(''),
),
);
@pragma('vm:entry-point')
Future<void> backgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
initFirebase();
// _configureRemoteMessage(message);
}
void initFirebase() async {
// final message = await FirebaseMessaging.instance.getInitialMessage();
await flutterLocalNotificationsPlugin.initialize(
_initSettings,
onDidReceiveNotificationResponse: _configurePayloadMessage,
onDidReceiveBackgroundNotificationResponse: _configurePayloadMessage,
);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
// FirebaseMessaging.onMessageOpenedApp.listen(_configureRemoteMessage);
FirebaseMessaging.onMessage.listen(_configureRemoteMessage);
FirebaseMessaging.onMessageOpenedApp.listen(_configurePayloadMessageClick);
await _handleInitialMessage();
}
Future<void> _handleInitialMessage() async {
final RemoteMessage? message =
await FirebaseMessaging.instance.getInitialMessage();
if (message != null) {
// Lưu payload
AppStateStore().setPushPayload(PushPayloadModel.fromNotification(message));
if (SdkController.isSessionOpened) {
handlePayloadNavigation(message.data);
}
}
}
@pragma('vm:entry-point')
Future<void> _configurePayloadMessage(NotificationResponse response) async {
// alwasy get payload from notification
if (response.payload == null || response.payload!.isEmpty) return;
final payload = _convertStringToJson(response.payload);
AppStateStore().setPushPayload(
PushPayloadModel(
type: payload['type'] as String?,
username: payload['username'] as String?,
data: payload,
),
);
if (SdkController.isSessionOpened) {
handlePayloadNavigation(payload);
}
}
Future<void> _configurePayloadMessageClick(RemoteMessage message) async {
final payload = message.data;
if (payload.isEmpty) return;
AppStateStore().setPushPayload(PushPayloadModel.fromNotification(message));
if (SdkController.isSessionOpened) {
handlePayloadNavigation(payload);
}
}
void handlePayloadNavigation(Map<String, dynamic> payload) {
if (payload['type'] == NotificationEnum.authorization.value) {
final authRequest = _convertStringToJson(payload['authorizationRequest']);
Get.toNamed(
AppRoutes.routeAuthorize,
arguments: Authorize.fromJson(authRequest),
);
} else if (payload['type'] == NotificationEnum.signing.value) {
final signRequest = _convertStringToJson(payload['signingRequest']);
Get.toNamed(
AppRoutes.routeConfirmSign,
arguments: Sign.fromJson(signRequest),
);
}
}
Future<void> _configureRemoteMessage(RemoteMessage message) async {
final notification = message.notification;
if (GetPlatform.isAndroid && notification != null) {
flutterLocalNotificationsPlugin.show(
message.hashCode,
notification.title,
notification.body,
_notificationDetails,
payload: jsonEncode(message.data),
);
}
}
Map<String, dynamic> _convertStringToJson([String? data]) {
return Map<String, dynamic>.from(jsonDecode(data ?? '{}'));
}
class HomeController extends BaseRefreshGetxController with GetSingleTickerProviderStateMixin {
@override
void onReady() {
getTotal();
_handlePushPayload();
super.onReady();
}
void _handlePushPayload() {
final payload = state.pushPayloadModel;
if (payload == null ||
payload.type == null ||
payload.username != state.userInfoModel.login) {
return;
}
handlePayloadNavigation(payload.data!);
state.clearPushPayload();
}
}
class AppStateStore {
PushPayloadModel? pushPayloadModel;
void setPushPayload(PushPayloadModel payload) {
pushPayloadModel = payload;
}
void clearPushPayload() {
pushPayloadModel = null;
}
}
I am working on push notification handling in Flutter and I am facing a problem with FirebaseMessaging.getInitialMessage().
My app uses flutter_local_notifications to display notifications manually when a Firebase data message arrives.
The notification opens the app correctly, but getInitialMessage() always returns NULL, even when the app is fully terminated and launched by tapping the notification.
This is the log I get every time:
I/flutter: 🔵 [FIREBASE] getInitialMessage: NULL
I/flutter: 🔵 [FIREBASE] _handleInitialMessage - message: NULL
Expected behavior
When the app is killed and the user taps a notification, getInitialMessage() should return the notification data so I can navigate to a specific screen.
Actual behavior
getInitialMessage() returns NULL every time.