skip to Main Content

I am using the flutter_local_notification package to handle notifications from a third party server (not firebase cloud messaging). Because I am using firebase but not firebase messaging, I am using the onSelectNotification function of the flutter-local_notification package.

This is the function that I pass to onSelectNotification:

static _selectNotification(String payload, StreamChatClient client, RemoteMessage message) {
    debugPrint('notification payload: $payload');

    if(payload.contains('livestream')) {
      Utils.db.getLiveRoom(payload.split(":")[1]).then((liveRoom) {
        Navigator.push(
          NavigationService.navigatorKey.currentContext!,
          MaterialPageRoute<void>(builder: (context) => LiveRoomChat(liveRoom: liveRoom)),
        );
      });
    }
    else {
      List<String> ids = message.data['channel_id'].toString().split('_');
      String receiverId = '';
      if(ids[0] == Utils.user?.uid) {
        receiverId = ids[1];
      }
      else {
        receiverId = ids[0];
      }

      Navigator.push(
        NavigationService.navigatorKey.currentContext!,
        MaterialPageRoute<void>(builder: (context) => MessageApi(
            sourceType: Utils.friends.containsKey(receiverId) ? SourceType.friends : SourceType.justMet,
            receiverId: receiverId,
            channelId: payload.split(":")[1],
            streamToken: Utils.user?.streamToken ?? '',
            client: client
        )),
      );
    }
  }

I have a global navigator key which I have defined in a NavigationService class, and I also assign this navigator key in the main.dart. This notification handling above works for ios but it does not work for android because NavigationService.navigatorKey.currentContext is always null on android. Does anyone know why this is the case on android, and what is the way to handle it?

3

Answers


  1. Can you try to run your code inside that?

    @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback((_) {
         _selectNotification();
        });
      }
    

    if you are not running your code in initstate try sending buildcontext to your function

    static _selectNotification(BuildContext context, String payload, StreamChatClient client, RemoteMessage message) {}
    
    Login or Signup to reply.
  2. I will share my project work flow it may help you.

    Initialized FlutterLocalNotificationsPlugin instance as global variable(above main() method).

    Defined a class GlobalVariable in main.dart

    passing GlobalVariable.navState to parameter nagavigatorKey of MaterialApp in MyApp class.

    in initState method of _MyAppState, initialized the flutterLocalNotificationPlugin.

    in onSelectNotification method, made Navigation call within SchedulerBinding.instance.addPostFrameCallback.

    Defined route of page in routes.dart file.

    Please check the code. You may find anything useful.

        import ....
    
    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
                FlutterLocalNotificationsPlugin();
    
        void main() async {
          WidgetsFlutterBinding.ensureInitialized();
            runApp(MyApp());
        }
    
    
      onSelectNotification(String payload) async {
                
        SchedulerBinding.instance.addPostFrameCallback((_) {
                    GlobalVariable.navState.currentState.pushNamed(
                        give routeName,
                        arguments: givearguments);
                  });    
         
      }
    
    
        class GlobalVariable {
           static final GlobalKey<NavigatorState> navState = GlobalKey<NavigatorState>();
        }
    
        class MyApp extends StatefulWidget {
          @override
          _MyAppState createState() => _MyAppState();
        }
        
        class _MyAppState extends State<MyApp> {
          
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              navigatorKey: GlobalVariable.navState, //this is must
              debugShowCheckedModeBanner: false,
              title: 'Home',
              home: ScreenOne(),
              routes: routes,
            );
          }
        
          @override
          void initState() {
            var initializationSettingsAndroid =
                new AndroidInitializationSettings('@mipmap/ic_launcher');
        
            var initializationSettings = new InitializationSettings(
                android: initializationSettingsAndroid);
            flutterLocalNotificationsPlugin.initialize(initializationSettings,
                onSelectNotification: onSelectNotification);
            registerNotification();
            super.initState();
          }
        
          @override
          void dispose() {
            WidgetsBinding.instance.removeObserver(this);
            super. Dispose();
          }
        }
    
    Login or Signup to reply.
  3. Did you mention permission inside your android manifest file?

     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    

    you will find their manifest file for example here

    Example manifest file link

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search