How to navigate notification to related page?

Issue

I am trying to navigate my notifications while terminated, opened. I can navigate when app is open but not on screen. In my home page’s initstate method, I created onMessageOpenedApp method to catch notification then call the api. Here is firebase messaging configuration.

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
AppleNotification? apple = message.notification?.apple;
if (notification != null && !kIsWeb) {
  flutterLocalNotificationsPlugin.show(
  notification.hashCode,
  notification.title,
  notification.body,
  NotificationDetails(
      android: AndroidNotificationDetails(
        channel.id,
        channel.name,
      ),
      iOS: const IOSNotificationDetails()),
  );
}
}

Future<void> iniciliazarFlutterLocalNotifications() async {
  final NotificationAppLaunchDetails? notificationAppLaunchDetails = !kIsWeb &&
      Platform.isLinux
  ? null
  : await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();

var androidSettings =
  const AndroidInitializationSettings('mipmap/launcher_icon');

FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

if (!kIsWeb) {
  channel = const AndroidNotificationChannel(
    'high_importance_channel', // id
    'High Importance Notifications', // title/ description
    importance: Importance.high,
    ledColor: Colors.blue);

var iOSSettings = const IOSInitializationSettings(
  requestSoundPermission: false,
  requestBadgePermission: false,
  requestAlertPermission: false,
);
var initSetttings =
    InitializationSettings(android: androidSettings, iOS: iOSSettings);
flutterLocalNotificationsPlugin.initialize(initSetttings);

await flutterLocalNotificationsPlugin
    .resolvePlatformSpecificImplementation<
        AndroidFlutterLocalNotificationsPlugin>()
    ?.createNotificationChannel(channel);

await flutterLocalNotificationsPlugin
    .resolvePlatformSpecificImplementation<
        IOSFlutterLocalNotificationsPlugin>()
    ?.requestPermissions(
      alert: true,
      badge: true,
      sound: true,
    );

await FirebaseMessaging.instance
    .setForegroundNotificationPresentationOptions(
  alert: true,
  badge: true,
  sound: true,
);

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  RemoteNotification? notification = message.notification;
  AndroidNotification? android = message.notification?.android;
  AppleNotification? apple = message.notification?.apple;
  if (notification != null && !kIsWeb) {
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
          ),
          iOS: const IOSNotificationDetails()),
    );
  }
});
}
}

And here is my HomeScreen initState variables that only I can navigate my notification then call Api provider.

class Home extends StatefulWidget {
 const Home({super.key});

 @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  void initState() {
    super.initState();
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
  if (message.data.containsKey('idReferance')) {
    Provider.of<CustomerProvider>(context, listen: false)
        .getTrackingInformationList(TrackingInformationFilterRequestModel(
            searchBox: message.data['idReferance']));
  }
 });
 }
 @override
 Widget build(BuildContext context) {
 return Container();
}

}

Solution

There is a function called getInitialMessage which returns the remote notifiction if the app is opened from notification when it is terminated.
if the app is opened from other places it will return null. You can handle the navigation according to this remote notification object. Here is a sample function you can use

Future<void> setupInteractedMessage() async {
    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage != null) {
      _handleMessage(initialMessage);
    }

    // Also handle any interaction when the app is in the background via a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

you can call this method from initstate from your app splash screen or some where you find it relevant. You can see example in this link for more detail
https://firebase.flutter.dev/docs/messaging/notifications/#handling-interaction

Answered By – umuieme

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *