firebase_messaging onResume 和 onLaunch 不起作用
Posted
技术标签:
【中文标题】firebase_messaging onResume 和 onLaunch 不起作用【英文标题】:firebase_messaging onResume and onLaunch not working 【发布时间】:2019-09-25 06:25:44 【问题描述】:当应用程序在前台时我会收到通知,但当应用程序在后台时不会。此外,我已经 google-ed/***-ed 了大约 2 小时或更长时间,但能够解决这个问题。
我的配置是:
firebase_auth: ^0.10.0
firebase_messaging: ^5.0.0
清单是这样的:
代码是这样的:
final notifications = new FirebaseMessaging();
class AppNotifications
static String fcmToken = '';
static Future<Null> init() async
appLogs("AppNotifications init");
notifications.requestNotificationPermissions(const iosNotificationSettings(sound: true, badge: true, alert: true));
await configure();
fcmToken = await notifications.getToken();
appLogs("FCM TOKEN : " + fcmToken);
notifications.onTokenRefresh.listen((newToken)
fcmToken = newToken;
appLogs("FCM TOKEN onTokenRefresh: " + fcmToken);
);
await updateFCMToken();
static Future<Null> configure() async
appLogs("AppNotifications Configure");
notifications.configure(onMessage: (msg)
appLogs('FCM onMessage: ' + msg.toString());
, onLaunch: (lun)
appLogs('FCM onLaunch: ' + lun.toString());
, onResume: (res)
appLogs('FCM onResume: ' + res.toString());
);
static Future<Null> updateFCMToken() async
auth.currentUser.fcmToken = fcmToken;
await updateUserInSharedPreference();
我这样调用函数:
class HomeScreenState extends State<HomeScreen>
@override
void initState()
super.initState();
Future.delayed(Duration(milliseconds: 100), () async
await AppNotifications.init();
);
..... ....
我正在使用邮递员发送通知:
我的日志:
**(App is Foreground)** I/flutter (31888): APPLOGS : FCM onMessage: notification: title: Test notification title, body: Test notification body, data: status: done, id: 1, foo: bar, click_action: FLUTTER_NOTIFICATION_CLICK
**(App is Background)** W/FirebaseMessaging(31888): Missing Default Notification Channel metadata in androidManifest. Default value will be used.
颤振医生:
[✓] Flutter (Channel stable, v1.2.1, on Mac OS X 10.14.4 18E226, locale en-GB)
• Flutter version 1.2.1 at /Users/Ajay/SDK/flutter
• Framework revision 8661d8aecd (3 months ago), 2019-02-14 19:19:53 -0800
• Engine revision 3757390fa4
• Dart version 2.1.2 (build 2.1.2-dev.0.0 0a7dcf17eb)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
• Android SDK at /Users/Ajay/Library/Android/sdk
• Android NDK location not configured (optional; useful for native profiling support)
• Platform android-28, build-tools 28.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
• All Android licenses accepted.
[✓] iOS toolchain - develop for iOS devices (Xcode 10.2.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 10.2.1, Build version 10E1001
• ios-deploy 1.9.4
• CocoaPods version 1.6.0
[✓] Android Studio (version 3.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin version 34.0.1
• Dart plugin version 182.5215
• Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
[!] VS Code (version 1.33.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
✗ Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (1 available)
• ONEPLUS A5000 • b47e8396 • android-arm64 • Android 9 (API 28)
【问题讨论】:
我也在为 Android 上的通知支持而苦苦挣扎。除了应用程序在前台时我没有收到通知。但即使有“后台到达”通知,数据有效负载也会在应用启动时丢失。 iOS 运行得非常好。 我终于通过在runApp(MyApp())
中初始化 Firebase 解决了我的 Firebase 消息传递问题。由于您似乎已经这样做了,您的代码流和我的代码流之间的唯一区别是您使用版本5.0.0
。你试过降级吗?例如。我用4.0.0+4
。
@George 当从 API.onLaunch 收到推送通知时,必须单击操作参数,并且未调用 onResume。
@AjayKumar 你解决了这个问题吗?
如果您针对 Android 设备,建议使用 @ShangariC click_action
。否则,当用户单击托盘中的通知时,不会调用 onLaunch
/ onResume
。有关详细信息,请查看文档中的 Sending Messages。
【参考方案1】:
我花了 2 天时间来解决这个问题,它可能对你有帮助。 notification 标记仅用于显示通知。您只能访问 onResume/onLaunch 上的数据内容。
如果你想在 onResume/onLaunch 中处理通知消息,也可以在 data 标签中添加这些消息,然后你可以做任何你想做的事情。
refer more detail on this link
发送此通知消息
"notification":
"body": "body",
"title": "title"
,
"priority": "high",
"data":
"body": "body",
"title": "title"
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"id": "1",
"status": "done",
"image": "https://ibin.co/2t1lLdpfS06F.png",
,
"to": <your token>
您将收到以下关于Resume 或onLaunch 的信息,您的通知标签在此处为空
notification: , data: image: https://ibin.co/2t1lLdpfS06F.png, google.original_priority: high, google.sent_time: 1560858283888, google.delivered_priority: high, body: body , title: title, click_action: FLUTTER_NOTIFICATION_CLICK, google.message_id: 0:1560858283908500%eefdc741eefdc741, collapse_key: <package>, google.ttl: 2419200, from: <from>, id: 1, status: done
您可以使用添加在数据标签中的标题和正文。
【讨论】:
这是正确答案!click_action
键需要在 data
对象内。 Firebase 没有记录在案。
当 click_action 是 n 通知而不是数据时它正在工作?
完全同意 Anand Saga ,
在一些教程中,他们提到了会导致此问题的“clickAction”
@MDavid 你能告诉我我在哪条路线上放了firebase init的代码吗?我已经添加了这个,但仍然没有工作。通知在后台显示,但 onResume 不起作用..【参考方案2】:
就我而言,onResume
和 onLoad
没有触发,因为我在 notification
属性下缺少 click_action: 'FLUTTER_NOTIFICATION_CLICK'
,不是data
属性。
一旦我将有效载荷更改为以下格式,onResume
和 onLoad
就开始为我触发。
notification:
title: 'Title',
body: 'Body',
click_action: 'FLUTTER_NOTIFICATION_CLICK'
我发现这个记录在here。
如果您在 TypeScript(可能是其他人)中设置它,则需要通过消息的 android.notification.clickAction
属性进行设置。否则,您可能会收到有关属性无效的错误。 MulticastMessage
的示例如下。请注意,它不会从头到尾显示消息构造;仅足以显示设置clickAction
的上下文。
// Initialize the notification
const notification: admin.messaging.Notification =
title: 'Hello',
// Though the "clickAction" property is available here, it throws an error about
// having an invalid property when actually trying to send the notification.
// Instead, the "clickAction" property is set further downstream under the
// MulticastMessage.android.notification object.
// clickAction: 'FLUTTER_NOTIFICATION_CLICK'
;
// Do other things to build your notification
const message: admin.messaging.MulticastMessage =
tokens: [],
notification: notification
;
// Do other things to build your message
// If a notification is being sent then set the click_action
if (message.notification)
// Combine with the existing message.android object, if one exists
message.android = message.android || ;
message.android.notification = Object.assign(message.android.notification || ,
clickAction: 'FLUTTER_NOTIFICATION_CLICK'
);
【讨论】:
如果放置在数据标签内,它会启动我的活动。但 onResume 和 onLoad 不起作用。 如果我将它添加到notification
有效负载中,我会收到此错误:Invalid JSON payload received. Unknown name "click_action" at \'message.notification\': Cannot find field.
我更新了我的答案,以展示我们如何在代码中设置它的示例。【参考方案3】:
在本节 link to plugin docs 中的 firebase_messaging 包的文档中,他们说您需要将 click_action: FLUTTER_NOTIFICATION_CLICK
作为“自定义数据”键值对包含在您的 onResume
和 @ 的服务器端发布请求中987654325@要调用的方法。
例如,这里使用the php firebase admin sdk 向 FCM 发送通知,这是发送通知的代码示例:
$factory = (new Factory)->withServiceAccount('path to firebase keys json file');
$messaging = $factory->createMessaging();
$deviceToken = $user->deviceToken;
$message = CloudMessage::withTarget('token', $deviceToken)
->withNotification(Messaging\Notification::create('title', 'body'))
->withData(['custom-data-key1' => 'custom-data-value1', 'custom-data-key2' => 'custom-data-value2', 'click_action'=>'FLUTTER_NOTIFICATION_CLICK']);
$messaging->send($message);
【讨论】:
【参考方案4】:您可能在 AndroidManifest 中缺少一些元数据(正如您的日志告诉您的那样)。 您需要在清单中添加以下内容:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id"/>
好像是duplicate
【讨论】:
【参考方案5】:Anand saga 发布的答案是正确的
您需要在数据部分添加标题和正文。通知负载将是空白 onResume 和 onLaunch 虽然它是从后端 nodejs API 发送的。
以下是 Flutter 解析为 onResume 的示例负载:
on resume notification: , data: image: https://ibin.co/2t1lLdpfS06F.png, google.original_priority: normal, google.sent_time: 1577389234347, google.delivered_priority: normal, body: "Custom Body", type: OrderDetail, title: "Custom title", click_action: FLUTTER_NOTIFICATION_CLICK, google.message_id: 0:1577389234352165%dfef845edfef845e, collapse_key: <<App NAme>>, google.ttl: 2419200, from: 790713779055, id: "5e050c04c308f6abb5a60b2e"
典型的 dart 配置如下所示。
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async
print('on message $json.encode(message['data']['title'])');
redirectScreenOnLoad(message);
,
onResume: (Map<String, dynamic> message) async
firebaseMessaging.onTokenRefresh;
print('on resume $message');
redirectScreenOnLoad(message);
,
onLaunch: (Map<String, dynamic> message) async
firebaseMessaging.onTokenRefresh;
// await API.updateUserApiToGetFCMKey();
print('on launch $message');
redirectScreenOnLoad(message);
,
);
在 redirectScreenOnLoad(String message) 中,我正在检查输入负载并重定向到不同的屏幕
【讨论】:
这是在 Android 上,但在 iOS 中 [data] 在 json 中不存在,你是否也为 iOS 解决了这个问题我上周一直在使用这个在 onResume 上工作但在 onLaunch 上失败 我没有在 iOS 中测试过这个。你能发布你在 iOS 中从 firebase 消息中得到的响应吗? 让它工作我需要从 initiState 调用才能工作 redirectScreenOnLoad() 函数在哪里? 这是一个配置问题,您需要完全执行文档中的步骤,它会起作用【参考方案6】:要为 FCM 故障排除添加的另一件事是在您的 onMessage
处理中。
首先,在onMessage
中,打印输出以查看您的设备是否正在接收消息。通知可能会在这一点之后失败并且不会显示,所以很高兴知道它是否得到它。如果是,那么您知道您已正确配置 FCM,并且您的问题在于您的 UI 处理。
接下来,检查onMessage
打印语句并确保您对数据的处理正确无误。我注意到 Android 数据的结构模式与 iOS 类型不同——因此这可能会导致您错误地解析数据,这可能不会显示通知,也不会引发错误。
这是我的意思的一个例子:
_fcm.configure(
onMessage: (Map<String, dynamic> message) async
print("onMessage: $message");
String sender;
String parsedMessage;
if (Platform.isAndroid)
sender = message['notification']['title'];
parsedMessage = message['notification']['body'];
if (Platform.isIOS)
sender = message['aps']['alert']['title'];
parsedMessage = message['aps']['alert']['body'];
,
);
您可以看到,我根据平台不同地解析相同的数据。如果不这样做,则通知永远不会出现,也不会指示失败。
同样,这只是在您拆开 .ts/.js 云函数之前尝试的操作。
【讨论】:
【参考方案7】:如果您的 android 应用程序在 kotlin 中,您应该将其添加为您的应用程序活动
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
class Application : FlutterApplication(), PluginRegistrantCallback
override fun onCreate()
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
override fun registerWith(registry: PluginRegistry?)
io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
别忘了将它添加到您的 Manifist
android:name=".Application"
【讨论】:
【参考方案8】:onLaunch: (Map<String, dynamic> msg)
print("Called onLaunch");
print(msg);
if(msg['data']['screen'].toString() == 'chat')
//Navigate to chat screen
return null;
,
【讨论】:
【参考方案9】:处理 firebase 消息的完整指南:
handleMessaging()
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async
// showNotification(
// message['notification']['title'], message['notification']['body']);
print("onMessage: $message");
print('Data is: '+ message['data']['screen'].toString());
,
onLaunch: (Map<String, dynamic> msg)
print("Called onLaunch");
print(msg);
print('Data is: '+ msg['data']['screen'].toString());
if(msg['data']['screen'].toString() == 'Chat Screen')
return //Navigate to chatApp();
return null;
,
onResume: (Map<String, dynamic> msg)
//(App in background)
// From Notification bar when user click notification we get this event.
// on this event navigate to a particular page.
print(msg);
// // Assuming you will create classes to handle JSON data. :)
// Notification ns = Notification(title: msg['title'], body: msg['body']);
//
return null;
,
// onMessage: (Map<String, dynamic> msg)
// // (App in foreground)
// // on this event add new message in notification collection and hightlight the count on bell icon.
// // Add notificaion add in local storage and show in a list.
);
【讨论】:
【参考方案10】:请注意,新版本的 FirebaseMessaging 是一个很大的变化,因此如果您发现此线程,以上所有内容都将不起作用。
Configure 消失了,与其他 Flutter 2 更新一样,都是通过 .listen 方法进行的。 有一个线程: How to configure Firebase Messaging with latest version in Flutter?
【讨论】:
以上是关于firebase_messaging onResume 和 onLaunch 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
firebase_messaging:^4.0.0+4 不工作
使用颤振 firebase_messaging 插件发送通知声音
firebase_messaging/unknown:Flutter IOS 出现未知错误