当应用程序在后台运行时调用 onMessage 方法

Posted

技术标签:

【中文标题】当应用程序在后台运行时调用 onMessage 方法【英文标题】:Call onMessage method when the app is in background in flutter 【发布时间】:2019-02-06 11:23:28 【问题描述】:

我是颤振和飞镖的新手。我正在尝试将我的应用程序与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);
 );

【问题讨论】:

FCM?什么是 FCM? @SomeGuy 你解决了后台推送通知吗?对我来说,前台正在工作,当应用程序在后台时,onResume 没有调用。对此有任何帮助 这里有同样的问题。任何线索如何解决这个问题? 【参考方案1】:

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

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

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

只有当用户选择这些通知之一时,应用才会知道该通知。

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

如果应用在后台,当用户选择通知时会触发onResume,将应用恢复到前台状态。

编辑:

正如@boformer 所指出的,这仅适用于“通知”消息。如果您发送“数据”消息,则不会创建通知,并且消息仅通过onMessage 传递。 the plugin readme 和 firebase docs 中的更多详细信息。

【讨论】:

请注意,仅当消息有效负载包含“通知”时才会创建通知。如果您使用数据消息,则不会创建通知 谢谢,已添加该信息! 当我的应用处于后台并且用户不点击和通知时,我如何才能收到推送消息? @rcorbellini 你找到解决办法了吗,我也遇到了类似的问题?? 不,我仍然坚持这一点。【参考方案2】:

根据上一个插件 Firebase Cloud Messaging for Flutter 版本 4.0.0+1,当您在控制台或表单上创建或编译推送通知时 ma​​ke一定要包括

click_action: FLUTTER_NOTIFICATION_CLICK 

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

【讨论】:

【参考方案3】:

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

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

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

查看 firebase_messaging 插件的源代码以了解在本机端发生了什么确实很有帮助。

【讨论】:

_firebaseMessaging.configure 有参数 onBackgroundMessage。您可以指定一个处理程序,该处理程序确定在后台收到消息时要做什么。如果您发送“通知”消息,它仍会将其放入托盘中,但您可以在代码中静默接收“数据”消息。见:pub.dev/packages/firebase_messaging【参考方案4】:

要在后台处理消息,请将 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);
  ,
);

【讨论】:

以上是关于当应用程序在后台运行时调用 onMessage 方法的主要内容,如果未能解决你的问题,请参考以下文章

从后台调用应用程序时调用方法

仅在应用处于后台时调用的静默通知回调方法

从后台被杀死的应用程序中恢复 - 重新启动时调用哪些方法?

在后台推送通知

在 GCM onMessage() 中显示对话框

接收方 FCM 通知点击事件