web-dev-qa-db-fra.com

comment ouvrir un écran particulier en cliquant sur Notification push pour flutter

J'essaie d'obtenir un écran spécifique ouvert en cliquant sur Notification push et ma charge utile ressemble à ceci:

 var payload = {
        notification: {
            title: notificationTitle,
            body: notificationMessage,
            click_action:"/screena",sound:"default",
        }
    };

Je reçois une notification, mais je ne parviens pas à détecter l'événement de clic de notification pour savoir comment l'attraper. J'utilise la messagerie flottante

https://github.com/flutter/plugins/tree/master/packages/firebase_messaging

et mon code de service de message push Firebase ressemble à ceci

 pushMessagingService() async{
messagingreference.configure(
onMessage: (Map<String, dynamic> message) {

  print("I am here in on message");
  print(message);
},
onLaunch: (Map<String, dynamic> message) {
  print("I am here onLaunch");
  print(message);
},
onResume: (Map<String, dynamic> message) {
  print("I am hereonResume");
  print(message);
},
);
  messagingreference.requestNotificationPermissions(
  const IosNotificationSettings(sound: true, badge: true, alert: true));
 messagingreference.onIosSettingsRegistered
  .listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
 });
 messagingreference.getToken().then((String token) async {


print(token);
 });
 }

ici, je peux obtenir le message comme @xqwzts l'a dit dans le message lorsque mon application est au premier plan, mais ma question est de savoir comment capturer l'événement de clic à partir de la notification Push soulevée dans la barre d'état système et naviguer vers l'écran requis.

18
siva kumar

Quelques choses ici:

1- click_action Doit être réglé sur "FLUTTER_NOTIFICATION_CLICK"

2- click_action Doit être défini dans la section data d'une charge utile

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

Cela devrait vous permettre de recevoir le message dans le gestionnaire onMessage de votre application flutter.

De là, vous pouvez appeler Navigator.of(context).pushNamed(message['screen']).

Si vous n'avez pas de BuildContext à ce stade, vous pouvez enregistrer un GlobalKey comme propriété navigatorKey de votre MaterialApp, et l'utiliser pour accéder à votre Navigator globalement, via GlobalKey.currentState

22
xqwzts

Comme la méthode @xqwzts fonctionne bien pour recevoir des messages sur l'application est ouverte,

l'exemple suivant va naviguer vers une page spécifique,

[LE CODE IS EXTRAIT DU CODE D'EXEMPLE DU PLUGIN DE MESSAGERIE FIREBASE UNIQUEMENT ET IL NAVIGUE SUR UNE PAGE NOMMÉE, DANS LAQUELLE LES DONNÉES WE ENVOYÉES VIA FIREBASE CONSOLE]

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

enter image description here

COMPRENDRE LES 2 CHOSES, LES NOTIFICATIONS DE LA FCM COMPRENNENT 2 SECTIONS

Titre du premier message La section de votre page de messagerie cloud Firebase est appelée Données de notification [lorsque l'application est supprimée ou fermée, elle sera affichée comme une notification]

La deuxième section du titre du message qui se trouve en bas de la page Web est appelée Données de message , [elles seront affichées dans l'application interne sous forme de notification ou de dialogue d'alerte c'est jusqu'à votre souhait]

[~ # ~] étapes [~ # ~] Créez un projet factice puis utilisez le plug-in de message Firebase, et dans cette boîte donne BMW Cars comme sujet et cliquez sur abonner

Maintenant, allez sur votre console, puis envoyez un message avec le FORMAT SUIVANT, il doit contenir les clés Id et Status parce que nous analysons l'identifiant et les clés d'état afin d'afficher NextPage avec la valeur de la clé d'état, mais si u préférez un champ comme le titre ou le corps, vous pouvez également le faire, mais assurez-vous d'analyser la valeur de la carte dans votre code de flottement.

//THIS IS A LITTLE BIT MODIFIED VERSION OF Example Code given in Firebase 
//Messagaing Plugin
//WHEN U PASTE THE CODE IN UR VSCODE 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(),
          ),
    );
  }
}
8
Rajesh Jr.