Skip to content

🐛 [FIREBASE_MESSAGING] Unable to navigate when the app is killed or switched to another app #11173

@itsmelaxman

Description

@itsmelaxman

Bug report

Describe the bug
I'm facing an issue where the app doesn't navigate to the desired screen when it is killed or on home. The navigation works fine when the app is in the foreground, but it fails to navigate when it is completely closed or not in focus.

Steps to reproduce

  1. Launch the app.
  2. Perform necessary actions to trigger a navigation event.
  3. Close the app or switch to another app.
  4. nReceive a notification or perform an action that should trigger a navigation.

Expected behavior

The app should navigate to the appropriate screen when a notification is received or an action is performed, regardless of whether the app is in the foreground, background, or completely closed. The app fails to navigate when it is completely closed or switched to another app. No error or exception is thrown.

Sample project

main.dart file

import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
}

Future<void> main(context) async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  runApp(
    MyApp(),
  );
}

class MyApp extends StatefulWidget {
 
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
 

  @override
  void initState() {
    super.initState();
    NotificationService().init();
  }

  @override
  Widget build(BuildContext context) {
  
    return MaterialApp(
                navigatorKey: navigatorKey,
                debugShowCheckedModeBanner: false,
                title: 'Demo',
                routes: globalRoutes,
                initialRoute initialRoute,
              );          
  }
}

notification_service.dart


@pragma('vm:entry-point')
onTapNotificationBackground(NotificationResponse notificationResponse) async {
  final String? payload = notificationResponse.payload;
  if (payload != null) {
    debugPrint('notification payload: $payload');
    await Utility.navigate(
      navigatorKey.currentState!.context,
      '/second-screen',
    
    );
  }
}

class NotificationService {
  final _messaging = FirebaseMessaging.instance;
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  Future<void> init() async {
    flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()!
        .requestPermission();

    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings(
      '@mipmap/ic_launcher',
    );

    final DarwinInitializationSettings initializationSettingsIOS =
        DarwinInitializationSettings(
           onDidReceiveLocalNotification:
          (int id, String? title, String? body, String? payload) async {
        onSelectNotificationResponse;
      },
    );

    var initializationSettings = InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );

    await flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
      onDidReceiveNotificationResponse: (payload) {
      
        onSelectNotificationResponse(payload);
        
      },
      onDidReceiveBackgroundNotificationResponse: onTapNotificationBackground,
    );

    FirebaseMessaging.onMessage.listen(
      (RemoteMessage event) {
        print('called');
        if (event!=null) {
          showLocalNotification(
            event.notification?.title,
            event.notification?.body,
            json.encode(event.data).toString(),
          );
        } else {
          print('---- onMessage called after ----');
        }
      },
    );

    FirebaseMessaging.onMessageOpenedApp.listen(
      (message) {
        print('---- onMessageOpenedApp called ----');
        if (message!=null) {
          Utility.navigate(
            navigatorKey.currentState!.context,
            '/second-screen',
          );
        } else {
          print('---- onMessageOpenedApp is not opened ----');
        }
      },
    );

    // workaround for onLaunch: When the app is completely closed (not in the background) and opened directly from the push notification
    _messaging.getInitialMessage().then(
      (message) {
        print('---- getInitialMessage called ----');
        if (message != null) {
         Utility.navigate(
            navigatorKey.currentState!.context,
            '/second-screen',            
          );
        } else {
          print('---- getInitialMessage is not opened ----');
        }
      },
    );

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

  Future<void> onSelectNotificationResponse(
      NotificationResponse notificationResponse) async {
    final String? payload = notificationResponse.payload;
    if (payload != null) {
      debugPrint('---- notification payload: $payload ----');

      await Utility.navigate(
        navigatorKey.currentState!.context,
        '/second-screen',
      );
    }
  }

  void showLocalNotification(String? title, String? message,
      [String? payload]) async {
    AndroidNotificationDetails androidPlatformChannelSpecifics =
        AndroidNotificationDetails(
      title ?? '',
      message ?? '',
      importance: Importance.max,
      priority: Priority.high,
      playSound: true,
      showWhen: false,
    );
    DarwinNotificationDetails iosPlatformChannelSpecifics =
        DarwinNotificationDetails(
      presentBadge: true,
      presentSound: true,
      presentAlert: true,
    );
    NotificationDetails platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
      iOS: iosPlatformChannelSpecifics,
    );
    await flutterLocalNotificationsPlugin.show(
      0,
      'this is title',
      'this is body',
      platformChannelSpecifics,
      payload: payload,
    );
  }
}

Additional Information:

Flutter version: 3.7.10
Device OS: Ubuntu 23.04
Dependencies and versions: [firebase_messaging: ^14.6.1, flutter_local_notifications: ^14.1.0]


Flutter doctor

Click To Expand
[!] Flutter (Channel unknown, 3.7.10, on Ubuntu 23.04 6.2.0-23-generic, locale en_US.UTF-8)
    ! Flutter version 3.7.10 on channel unknown at /home/edigitalnepal/flutter
      Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
      If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
    ! Unknown upstream repository.
      Reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
    • Framework revision 4b12645012 (3 months ago), 2023-04-03 17:46:48 -0700
    • Engine revision ec975089ac
    • Dart version 2.19.6
    • DevTools version 2.20.1
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and
      upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /home/edigitalnepal/Android/Sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /home/edigitalnepal/.local/share/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9971841/jbr/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • Ubuntu clang version 15.0.7
    • cmake version 3.25.1
    • ninja version 1.11.1
    • pkg-config version 1.8.1

[✓] Android Studio (version 2022.2)
    • Android Studio at /home/edigitalnepal/.local/share/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.9971841
    • Flutter plugin version 74.0.2
    • Dart plugin version 222.4582
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1)
    • IntelliJ at /home/edigitalnepal/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.9011.34
    • Flutter plugin version 73.0.2
    • Dart plugin version 222.4345.14

[✓] VS Code
    • VS Code at /snap/code/current
    • Flutter extension version 3.66.0

[✓] Connected device (3 available)
    • M2101K6G (mobile) • f7ff74f4 • android-arm64  • Android 13 (API 33)
    • Linux (desktop)   • linux    • linux-x64      • Ubuntu 23.04 6.2.0-23-generic
    • Chrome (web)      • chrome   • web-javascript • Google Chrome 114.0.5735.133

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.```


Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions