Search code examples
dartflutterflutter-layout

Flutter: local notification plugin, navigate to specific screen when the user tap the notification


I`m using local notification plugin and everything works fine except that when i tap on the notification.i want to navigate to specific screen when the user tap the notification

Future onSelectNotification(String payload) async {
    //convert payload json to notification model object
    try{
    Map notificationModelMap = jsonDecode(payload);
    NotificationModel model = NotificationModel.fromJson(notificationModelMap);

    await Navigator.push(
        context,// it`s null!
        new MaterialPageRoute(
            builder: (context) => CommitmentPage(model)));}
            catch(e){print(e.toString());}
  }

but the context always null and gives me an exception NoSuchMethodError: The method 'ancestorStateOfType' was called on null.

Edit

i tried to use navigatorKey and pass it to material app as suggested by @Günter Zöchbauer but it gives me another exception

Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget

main.dart

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

static final navigatorKey = new GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      navigatorKey:navigatorKey ,
      title: 'notification',
      theme: ThemeData(
        primarySwatch: Colors.purple,
      ),
      home: new RootPage(auth: new Auth(),),
    );
  }

}

ReminderPage

   class ReminderPage extends StatefulWidget {

    @override
      _ReminderPageState createState() => _ReminderPageState();

    }

class _ReminderPageState extends State<ReminderPage> {
  final flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
....

 @override
  void initState() {
    super.initState();

    _initLocalNotification();
....

  }


// this method is called when u tap on the notification
 Future onSelectNotification(String payload) async {

    //convert payload json to notification model object
    Map notificationModelMap = jsonDecode(payload);
    NotificationModel model = NotificationModel.fromJson(notificationModelMap);

    try{
   await Navigator.push(
        MyApp.navigatorKey.currentState.context,
        new MaterialPageRoute(
            builder: (context) => CommitmentPage(model)));}
            catch(e){print(e.toString());}


  }

}

Edit 2 instead of using

 await Navigator.push(
            MyApp.navigatorKey.currentState.context,
            new MaterialPageRoute(
                builder: (context) => CommitmentPage(model)));}
                catch(e){print(e.toString());}

i used

await  MyApp.navigatorKey.currentState.push(MaterialPageRoute(builder: (context) => CommitmentPage(model)));

and it worked fine, but when i tap on the notification after killing the app, it takes me to the home page not to the desired one! i think navigatorKey has not been initialized yet!


Solution

  • With the latest change you've done, you being taken to the home page, is more to do with the fact that you instantiate and initialise the plugin a couple of pages further in your app. considering the app got killed, the plugin would've been killed too. you should look into initialising the plugin closer to when your app starts e.g. around when the app is created or when the first page is created, depending on the behaviour you want. In this issue https://github.com/MaikuB/flutter_local_notifications/issues/99, another dev has been able to change the first page shown if the app is killed but that may different to what you want to happen.