how to open particular screen on clicking on push notification for flutter

前端 未结 6 1794
我寻月下人不归
我寻月下人不归 2020-12-02 07:14

I am trying to achieve open specific screen on clicking push notification and my payload looks like this:

 var payload = {
        notification: {
                  


        
相关标签:
6条回答
  • 2020-12-02 07:22

    Initially, @xqwzts answer not working for me. After a lot of research, I find that We need to initialize the configure method little delay. I attached the code below. It will helpful for others.

    void initState() {
            // TODO: implement initState
            super.initState();
            _firebaseMsgListener();
          }
    
          void _firebaseMsgListener() {
            // if (Platform.isIOS) iOS_Permission();
    
            _firebaseMessaging.getToken().then((token) {
              Fimber.d("=====> token : $token");
              UpdateTokenRequest request = UpdateTokenRequest();
              request.token = token;
              homeBloc.updateFCMToken(request);
            });
    
            Future.delayed(Duration(seconds: 1), () {
              _firebaseMessaging.configure(
                onBackgroundMessage: myBackgroundMessageHandler,
                onMessage: (Map<String, dynamic> message) async {
                  Fimber.d("=====>on message $message");
                  Fluttertoast.showToast(msg: "onMessage $message");
                },
                onResume: (Map<String, dynamic> message) async {
                  Fimber.d("=====>onResume $message");
                  Fluttertoast.showToast(msg: "onResume $message");
                },
                onLaunch: (Map<String, dynamic> message) async {
                  Fimber.d("=====>onLaunch $message");
                  Fluttertoast.showToast(msg: "onLaunch $message");
                },
              );
            });
          }
    
          Future<dynamic> myBackgroundMessageHandler(
              Map<String, dynamic> message) async {
            print("_backgroundMessageHandler");
            if (message.containsKey('data')) {
              // Handle data message
              final dynamic data = message['data'];
              print("_backgroundMessageHandler data: ${data}");
            }
    
            if (message.containsKey('notification')) {
              // Handle notification message
              final dynamic notification = message['notification'];
              print("_backgroundMessageHandler notification: ${notification}");
              Fimber.d("=====>myBackgroundMessageHandler $message");
            }
            return Future<void>.value();
          }
    
    0 讨论(0)
  • 2020-12-02 07:23

    As @xqwzts method works well for receiving messages on App is an open state,

    the following example will navigate to a specific page,

    [THE CODE IS TAKEN FROM THE FIREBASE MESSAGING PLUGIN EXAMPLE CODE ONLY AND IT NAVIGATES TO A NAMED PAGE, IN WHICH THE DATA WE SENT VIA FIREBASE CONSOLE]

    //eg: if you give /Nexpage3  in the status field then it will navigate to Nextpage3 of your App
    

    UNDERSTAND THE 2 THINGS,FCM NOTIFICATIONS HAS 2 SECTIONS

    1st Message Title Section in your firebase cloud messaging page is called Notification Data[when the App is minimized or closed it will be shown as a notification]

    2nd Message Title section which is in the bottom of the webpage is called Message Data, [it will be shown In inside app as a notification or an Alert dialogue that's up to your wish]

    STEPS Create a dummy Project then use firebase message plugin, and in that Box give BMW Cars as atopic and click subscribe

    Now go to your console then send a message with the FOLLOWING FORMAT it must contain Id and Status keys because we are parsing the Id and Status Keys in order to show NextPage with the Status Key's Value but if u prefer a field like title or body then u can do that too but make sure to parse the map value in ur flutter code.

    //THIS IS A LITTLE BIT MODIFIED VERSION OF Example Code given in Firebase 
    //Messaging Plugin
    //WHEN U PASTE THE CODE IN UR VS CODE OR ANDROID STUDIO PLEASE Format the 
    //Document because it is aligned in single lines
    
    import 'dart:async';
    import 'package:firebase_messaging/firebase_messaging.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        new MaterialApp(
          home: new PushMessagingExample(),
          routes: <String,WidgetBuilder>{
            "/Nexpage1":(BuildContext context)=> new Nexpage1(),
            "/Nexpage2":(BuildContext context)=> new Nexpage2(),
            "/Nexpage3":(BuildContext context)=> new Nexpage3(),
            } ),);}
    
    
    //INITIAL PARAMETERS
    String _homeScreenText = "Waiting for token...";
    bool _topicButtonsDisabled = false;
    final FirebaseMessaging _firebaseMessaging = new FirebaseMessaging();
    final TextEditingController _topicController = new TextEditingController(text: 'topic');
    final Map<String, Item> _items = <String, Item>{};
    Item _itemForMessage(Map<String, dynamic> message) {
      final String itemId = message['id'];
      final Item item = _items.putIfAbsent(itemId, () => new Item(itemId: itemId))..status = message['status'];
          return item;
    }
    
    //MAIN CLASS WHICH IS THE HOMEPAGE
    class PushMessagingExample extends StatefulWidget {
      @override
      _PushMessagingExampleState createState() => new _PushMessagingExampleState();
    }
    
    
    class _PushMessagingExampleState extends State<PushMessagingExample> {
    void _navigateToItemDetail(Map<String, dynamic> message) {
    final String pagechooser= message['status'];
    Navigator.pushNamed(context, pagechooser);
    }
    
    //CLEAR TOPIC
    void _clearTopicText() {setState(() {_topicController.text = "";_topicButtonsDisabled = true;});}
    
    //DIALOGUE
    void _showItemDialog(Map<String, dynamic> message) {showDialog<bool>(context: context,builder: (_) => _buildDialog(context, _itemForMessage(message)),).then((bool shouldNavigate) {if (shouldNavigate == true) {_navigateToItemDetail(message);}});}
    
    //WIDGET WHICH IS GOING TO BE CALLED IN THE ABOVE DIALOGUE
    Widget _buildDialog(BuildContext context, Item item) {return new AlertDialog(content: new Text("Item ${item.itemId} has been updated"),actions: <Widget>[new FlatButton(child: const Text('CLOSE'),onPressed: () {Navigator.pop(context, false);},),new FlatButton(child: const Text('SHOW'),onPressed: () {Navigator.pop(context, true);},),]);}
    
    
    @override
    void initState() {
    super.initState();
    _firebaseMessaging.configure(
    onLaunch: (Map<String, dynamic> message) async { _navigateToItemDetail(message);},
    onResume: (Map<String, dynamic> message) async { _navigateToItemDetail(message);},
    onMessage: (Map<String, dynamic> message) async {_showItemDialog(message);},);
    
    //GETTING TOKEN FOR TESTING MANUALY
    _firebaseMessaging.getToken().then((String token) {assert(token != null);setState(() {_homeScreenText = "Push Messaging token: $token";});print(_homeScreenText);});}
    
    
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(  title: const Text('Push Messaging Demo'),),
            body: new Material(
              child: new Column(
                children: <Widget>[
                  new Center(
                    child: new Text(_homeScreenText),
                  ),
                  new Row(children: <Widget>[
                    new Expanded(
                      child: new TextField(
                          controller: _topicController,
                          onChanged: (String v) {
                            setState(() {
                              _topicButtonsDisabled = v.isEmpty;
                            });
                          }),
                    ),
                    new FlatButton(
                      child: const Text("subscribe"),
                      onPressed: _topicButtonsDisabled
                          ? null
                          : () {
                              _firebaseMessaging
                                  .subscribeToTopic(_topicController.text);
                              _clearTopicText();
                            },
                    ),
    new FlatButton(child: const Text("unsubscribe"),
    onPressed: _topicButtonsDisabled? null: () { _firebaseMessaging.unsubscribeFromTopic(_topicController.text);
     _clearTopicText();},),
    
    ])],),));}}
    
    
    
    
    //THREE DUMMY CLASSES FOR TESTING PURPOSE 
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //PAGE1
    class Nexpage1 extends StatefulWidget {  @override  _Nexpage1State createState() => _Nexpage1State();}
    class _Nexpage1State extends State<Nexpage1> { @override Widget build(BuildContext context) { return Scaffold(body: new Center(child: new Text(" Page1"),));}}
    
    //PAGE2
    class Nexpage2 extends StatefulWidget {  @override  _Nexpage2State createState() => _Nexpage2State();}
    class _Nexpage2State extends State<Nexpage2> {  @override  Widget build(BuildContext context) {    return Scaffold(      body: Center(child: new Text("2pending"),)      );  }}
    
    //PAGE3
    class Nexpage3 extends StatefulWidget {  @override  _Nexpage3State createState() => _Nexpage3State();}
    class _Nexpage3State extends State<Nexpage3> {  @override  Widget build(BuildContext context) {    return Scaffold(      body: Center(child: new Text("3connected"),)      );  }}
    
    
    //THIS IS THE CLASS WHICH IS USED TO PARSE THE INFORMATION
    class Item {
      Item({this.itemId});
      final String itemId;
      StreamController<Item> _controller = new StreamController<Item>.broadcast();
      Stream<Item> get onChanged => _controller.stream;
      String _status;
      String get status => _status;
      set status(String value) {
        _status = value;
        _controller.add(this);
    }
    
      static final Map<String, Route<Null>> routes = <String, Route<Null>>{};
      Route<Null> get route {
        final String routeName = '/detail/$itemId';
        return routes.putIfAbsent(
          routeName,
          () => new MaterialPageRoute<Null>(
                settings: new RouteSettings(name: routeName),
                builder: (BuildContext context) => new Nexpage3(),
              ),
        );
      }
    }
    
    0 讨论(0)
  • 2020-12-02 07:26
          onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        await print("onLaunch: $message");
        ///_navigateToItemDetail(message);
        await _showItemDialog(message); // Diyalog Kutusu Oluştur
      },
      onResume: (Map<String, dynamic> message) async {
        await print("onResume: $message");
        ///_navigateToItemDetail(message);      
        await _showItemDialog(message); // Diyalog Kutusu Oluştur
      },
    

    Add await is working

    0 讨论(0)
  • 2020-12-02 07:33

    A few things here:

    1- click_action has to be set to "FLUTTER_NOTIFICATION_CLICK"

    2- click_action has to be set in the data section of a payload

    DATA='{
      "notification": {
        "body": "this is a body",
        "title": "this is a title"
        "click_action": "FLUTTER_NOTIFICATION_CLICK",
      },
      "data": {
        "sound": "default", 
        "status": "done",
        "screen": "screenA",
      },
      "to": "<FCM TOKEN>"
    }'
    

    This should allow you to receive the message in the onMessage handler in your flutter app.

    From there you can call Navigator.of(context).pushNamed(message['screen']).

    If you don't have a BuildContext at that point, you can register a GlobalKey as the navigatorKey property of your MaterialApp, and use it to access your Navigator globally, via GlobalKey.currentState

    0 讨论(0)
  • 2020-12-02 07:43

    Step 1: pass one key-value pair in the firebase notification as click_action: FLUTTER_CLICK_ACTION.

    Step 2: Using step 1 you'll receive the onTap callback of notification inside onResume or onLaunch method.

    Step 3: Perform the following scenario for navigating to a specific screen on click of notification.

    • When you build your MaterialApp, pass a navigatorKey parameter which specifies the key to use for the navigator and then assign that key to your material app as shown below:
    class _MyHomePageState extends State<MyHomePage> {
      final GlobalKey<NavigatorState> navigatorKey = GlobalKey(debugLabel: "Main Navigator");
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          navigatorKey: navigatorKey,
          home: new Scaffold(
            appBar: AppBar(),
            body: new Container(),
          ),
        );
      }
    }
    
    • Now, from the onResume or onLuanch method navigate to your screen using below line of code:
     navigatorKey.currentState.push(
        MaterialPageRoute(builder: (_) => Dashboard())
     );
    
    0 讨论(0)
  • 2020-12-02 07:48
        onLaunch: (Map<String, dynamic> message) {
          print("I am here onLaunch");
          print(message);
          Navigator.push(
           context,
           MaterialPageRoute(
            builder: (context) => ScreenA()
           )
          );
        },
        onResume: (Map<String, dynamic> message) {
          print("I am here onResume");
          print(message);
          Navigator.push(
           context,
           MaterialPageRoute(
            builder: (context) => ScreenA()
           )
          );
        },
    

    try this

    0 讨论(0)
提交回复
热议问题