当应用程序在背景中颤动时调用onMessage方法

时间:2018-08-31 12:14:03

标签: android dart firebase-cloud-messaging flutter android-notifications

我是新来的飞镖和飞镖。我正在尝试将我的应用与FCM连接。当应用程序在前台时,我创建flutterLocalNotificationsPlugin,并且一切正常,但是当我的应用程序在后台时,我不怎么处理onMessage方法。有人知道我该如何解决吗?

FirebaseMessaging firebaseMessaging = new FirebaseMessaging();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();

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

 var androidInitSettings = new AndroidInitializationSettings('mipmap/ic_launcher');
 var iosInitSettings = new IOSInitializationSettings();
 var initSettings = new InitializationSettings(androidInitSettings, iosInitSettings);
 flutterLocalNotificationsPlugin.initialize(initSettings, selectNotification: onSelectNotification);

 firebaseMessaging.configure(
   onLaunch: (Map<String, dynamic> msg) {
     print(" onLaunch called ${(msg)}");
   },
   onResume: (Map<String, dynamic> msg) {
     print(" onResume called ${(msg)}");
   },
   onMessage: (Map<String, dynamic> msg) {
     showNotification(msg);
     print(" onMessage called ${(msg)}");
   },
 );
 firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, alert: true, badge: true));
 firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings setting) {
   print('IOS Setting Registed');
 });
 firebaseMessaging.getToken().then((token) {
   update(token);
 });
}

4 个答案:

答案 0 :(得分:2)

根据最后一个插件 Flutter的Firebase Cloud Messaging 版本4.0.0 + 1,当您在控制台或表单上创建或编译推送通知时,

make一定要包括

click_action: FLUTTER_NOTIFICATION_CLICK 
定位Android设备时,将

作为“自定义数据”键值对(在“高级选项”下)。 此选项可在您的应用处于后台状态时启用onResume

答案 1 :(得分:1)

在后台运行该应用程序时,Dart VM无法运行。这意味着您必须使用本机代码(Java / Kotlin / ObjectiveC / Swift)处理通知和数据消息。

要在Android上执行此操作,请参考official documentation

您可能必须删除firebase_messaging插件并手动执行所有消息处理。要将通知内容发送到您的Flutter应用(处于前台状态),请使用平台渠道。

查看firebase_messaging插件的源代码以了解本机端的情况确实有帮助。

答案 2 :(得分:1)

我看到您在触发onMessage时强行显示通知,如果应用程序在后台运行,则不需要这样做,通知会自动创建。

当您收到通知并且该应用已打开且在前台运行时,将触发onMessage。例如,您已打开Gmail应用程序,并且收到了一封新电子邮件,在这种情况下,您不需要在通知区域中弹出通知。该应用程序可能会选择直接处理它,并且onMessage会在收到通知后立即触发-这很好,因此您无需继续池化服务器。

onResumeonLaunch有点不同-收到通知时不会触发这两个事件。仅当用户从通知区域选择/轻按通知时,才会触发它们。因此,在这两种情况下,该应用程序当前都处于隐藏状态,或者根本不运行(已终止),或者该应用程序处于后台状态-未显示。在这种情况下,通知会在手机中接收并自动放置在通知区域中(您无需为此编写代码“ showNotification”)。在这种状态下,用户可以看到通知,但应用本身尚未意识到该通知。

仅当用户选择这些通知之一时,应用程序才会意识到该通知。

如果应用程序根本没有运行,则用户点击通知时将触发onLaunch。这意味着该应用未运行,并且由于收到通知,它不得不“从头开始”。

如果应用在后台运行,则onResume将在用户选择通知时触发,将应用恢复为前台状态。

编辑:

@boformer指出,这仅适用于“通知”消息。如果您要发送“数据”消息,则不会创建任何通知,并且仅通过onMessage发送消息。在the plugin readmefirebase docs中有更多详细信息。

答案 3 :(得分:0)

要在后台处理消息,请将firebase-messaging实现添加到依赖项支架。

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
  if (message.containsKey('data')) {
    // Handle data message
    final dynamic data = message['data'];
  }

  if (message.containsKey('notification')) {
    // Handle notification message
    final dynamic notification = message['notification'];
  }

  // Or do other work.
}

并在onBackgroundMessage

的配置中调用它
 _firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    print("onMessage: $message");
    _showItemDialog(message);
  },
  onBackgroundMessage: myBackgroundMessageHandler,
  onLaunch: (Map<String, dynamic> message) async {
    print("onLaunch: $message");
    _navigateToItemDetail(message);
  },
  onResume: (Map<String, dynamic> message) async {
    print("onResume: $message");
    _navigateToItemDetail(message);
  },
);