当应用程序处于后台/终止并收到 FCM 通知时,如何在 Flutter 中显示本地通知?
Posted
技术标签:
【中文标题】当应用程序处于后台/终止并收到 FCM 通知时,如何在 Flutter 中显示本地通知?【英文标题】:How to show a Local Notification in Flutter, when the app is in Background/Terminated and it receives an FCM notification? 【发布时间】:2021-07-02 16:01:01 【问题描述】:我正在尝试在我的 Flutter 应用中使用 Firebase Cloud Messaging 实施推送通知服务。这就是 FCM 文档所说的我们应该根据应用的当前状态(前台、后台或终止)处理通知的方式:
前台:我们有一个 onMessage
流,我们可以收听,但 FCM 在前台状态时将不显示任何通知,所以我们必须使用FlutterLocalNotificationsPlugin
为此,这是我的实现:
FirebaseMessaging.onMessage.listen((RemoteMessage remoteMessage)
// calling flutter local notifications plugin for showing local notification
scheduleNotification(remoteMessage);
);
在scheduleNotification
方法中我调用FlutterLocalNotificationsPlugin().show()
方法,到目前为止一切正常。
问题从这里开始:
Background, Terminated:Firebase 会在此状态下自动显示通知,它有一个 onBackgroundMessage. 方法,我们可以将 BackgroundMessageHandler 传递给该方法在之后运行FCM 已显示通知。这是我对后台处理程序的实现:
Future<void> backgroundMessageHandler(
RemoteMessage remoteMessage) async
RemoteNotification? remoteNotification = remoteMessage.notification;
if (remoteNotification != null)
FlutterLocalNotificationsPlugin().show(
remoteMessage.messageId.hashCode,
remoteNotification.title,
remoteNotification.body,
NotificationDetails(
android: AndroidNotificationDetails(
_androidNotificationChannel.id,
_androidNotificationChannel.name,
_androidNotificationChannel.description,
icon: 'launch_background',
importance: Importance.max),
));
问题:每次我的应用收到 FCM 的通知时,我的应用都会显示 两个 通知,一个由 FCM 自动显示,第二个由我在BackgroundMessageHandler
中调用的FlutterLocalNotificationsPlugin().show()
方法。
Tl:dr
如何防止 FCM 自动显示任何通知并仅通过 FlutterLocalNotificationsPlugin().show()
方法显示?
一种解决方案是,我不从 FCM 发送通知,而只发送数据消息,而 FCM 不显示任何通知。但是,我不认为这是正确的方法。
【问题讨论】:
阅读此文,或许能有所帮助:***.com/questions/66934956/… 你用什么来发送通知? @CeltK.B.正如我在问题中提到的,我确实需要 onMessage 侦听器,当应用程序处于前台时,FCM 不会显示任何通知,只有 FlutterLocalNotifiationPlugin 会显示。这正是我想要的。问题是,当应用程序处于后台时,在这种情况下,FCM 显示一个通知,而 FlutterLocalNotificationPlugin 也显示一个通知,所以我得到 2 个通知,而不是一个。我希望 FCM 在任何状态下都不显示通知。 哟,可以看到你的代码吗?只是_firebaseMessagingBackgroundHandler()
部分?基本上,我只能在main()
上面定义这个,这让我很头疼!如果我将其声明到其他地方,则会收到 Null check operator used on a null value
错误。如果我只使用data
发送,那么它在 ios 上不起作用?你也让它在 iOS 上运行吗?
【参考方案1】:
我在这里回答我自己的问题, 经过一些研究,我在 FCM 文档中发现,如果我们想要处理在客户端显示通知,它确实提到使用仅数据消息。 我们可以阅读它here
客户端应用负责处理数据消息。数据消息只有自定义键值对,没有保留键名(见下文)。
当您希望 FCM 代表您的客户端应用处理显示通知时,请使用通知消息。当您想在客户端应用程序上处理消息时,请使用数据消息。
flutter fire docs里也提到了这个东西,
然后您的应用程序代码可以处理您认为合适的消息;更新本地缓存、显示通知或更新 UI。可能性无穷无尽!
这就是我猜的答案,我只是在传递 FCM 消息时不必使用“通知”字段,客户端上的 FCM 插件不会自动显示通知。我仍然认为应该在文档中更清楚地说明这一点,引起了很多混乱和研究,当我们的意图是向用户显示通知时,我仍然认为这有点奇怪,但我们仍然省略了“通知”字段.
【讨论】:
我也遇到了同样的问题,能否请您分享您的代码?我的firebase总是在后台调用通知并在通知中心显示内容所以我有双重通知☹️【参考方案2】:从上面的代码中删除FlutterLocalNotificationsPlugin().show
调用。您无需手动显示通知。
如您所说,运行此代码时已显示通知。
还是我错过了什么?
【讨论】:
FlutterLocalNotificationsPlugin().show 我确实需要这个调用,bcz 我想更喜欢本地通知而不是 FCM 自动显示的通知,bcz 的可定制性原因。无论如何我可以阻止 FCM 自动显示通知并且只使用 FlutterLocalNotificationsPlugin().show 吗?基本上我想做的与你的建议完全相反。 您可能想查看 iOS 中的静默推送通知。我不知道 Android 中是否有等价物,也不知道 Firebase 是否允许它们。也许this answer 可以提供帮助。 正如我在问题的最后一段中提到的那样,我确实考虑过使用“仅数据”消息,如果这是您的建议,但我认为这不是理想的方式,我我想我在某处读到“仅数据”消息,应该用于不重要的任务,通知不是其中之一 但是感谢答案的链接,如果没有其他方法,我将最终使用仅数据消息。 :) 我不认为仅仅显示本地通知就被认为是非平凡的。就我个人而言,我会考虑让推送通知适用于特定情况,但我不知道具体情况和您需要的定制。希望有人能够告诉您是否可以隐藏推送通知。【参考方案3】:我一开始也遇到了同样的问题,我省略了json中的通知发送,但是经过尝试和测试,我发现我可以发送通知和数据而没有双重推送通知的问题,它已经解决了。
解决方案:检查您的 onbackgroundhandler 并验证数据
if (message.data.message ['android_channel_id'] == my channel)
flutterLocalNotificationsPlugin.show();
【讨论】:
以上是关于当应用程序处于后台/终止并收到 FCM 通知时,如何在 Flutter 中显示本地通知?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter IOS 通知的 FCM 在应用程序处于后台或终止时不显示
Android - 包含 click_action 后未收到 FCM 推送通知
在 IOS 中未收到 FCM 推送通知。而应用程序在后台或终止。我使用 FirebaseMessaging 6.0.9 Pub