1

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.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.