Flutter firebase_恢复和启动时的消息不起作用
当应用程序位于前台时,我会收到通知,但当应用程序位于后台时,我不会收到通知。此外,我有谷歌ed/堆叠溢出大约2小时或以上,但能够解决这个问题 我的配置是:Flutter firebase_恢复和启动时的消息不起作用,flutter,push-notification,Flutter,Push Notification,当应用程序位于前台时,我会收到通知,但当应用程序位于后台时,我不会收到通知。此外,我有谷歌ed/堆叠溢出大约2小时或以上,但能够解决这个问题 我的配置是: firebase_auth: ^0.10.0 firebase_messaging: ^5.0.0 清单如下所示: final notifications = new FirebaseMessaging(); class AppNotifications { static String fcmToken = ''; st
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();
});
}
..... ....
代码如下所示:
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();
});
}
..... ....
颤振医生:
[✓] 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)
您的AndroidManifest中可能缺少一些元数据(如日志所示)。 您需要将以下内容添加到清单中:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id"/>
在我的例子中,
onResume
和onLoad
似乎没有触发,因为我缺少了click\u操作:NOTIFICATION
属性下的
,而不是data
属性
一旦我将有效负载更改为以下格式,onResume
和onLoad
开始为我启动
{
notification: {
title: 'Title',
body: 'Body',
click_action: 'FLUTTER_NOTIFICATION_CLICK'
}
}
我发现这是有记录的
如果您是在TypeScript(可能是其他)中进行设置,则需要通过消息的android.notification.clickAction
属性进行设置。否则,您可能会收到有关属性无效的错误。使用多播消息的示例如下所示。请注意,它不会从头到尾显示消息构造;仅足以显示设置的上下文单击操作
//初始化通知
常量通知:admin.messaging.notification={
标题:“你好”,
//虽然“clickAction”属性在此处可用,但它会引发一个关于
//在实际尝试发送通知时具有无效属性。
//相反,“clickAction”属性设置在
//MulticastMessage.android.notification对象。
//clickAction:“颤振\u通知\u单击”
};
//执行其他操作以生成通知
常量消息:admin.messaging.multicast消息={
代币:[],
通知:通知
};
//做其他事情来建立你的信息
//如果正在发送通知,则设置“单击”操作
if(message.notification){
//与现有message.android对象(如果存在)结合使用
message.android=message.android |{};
message.android.notification=Object.assign(message.android.notification |{}{
clickAction:“颤振\u通知\u单击”
});
}
我花了2天时间来解决此问题,这可能对您有所帮助。
通知标签仅用于显示通知。您只能访问onResume/onLaunch上的数据内容
如果您想在onResume/onLaunch中处理通知消息,请将这些消息也添加到data标记中,然后您可以做任何您想做的事情
发送此通知消息
{
"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>
}
{
“通知”:{
“身体”:“身体”,
“标题”:“标题”
},
“优先级”:“高”,
“数据”:{
“身体”:“身体”,
“标题”:“标题”
“点击动作”:“颤振通知点击”,
“id”:“1”,
“状态”:“完成”,
“图像”:https://ibin.co/2t1lLdpfS06F.png",
},
“致”:
}
您将在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}}
{通知:{},数据:{图片:https://ibin.co/2t1lLdpfS06F.png,google.original_priority:high,google.sent_time:1560858283888,google.delivered_priority:high,body:body,title:title,click_action:flatter_NOTIFICATION_click,google.message_id:0:1560858283908500%eefdc741eefdc741,collapse_key:,google.ttl:2419200,from:,id:1,status:done}}
您可以使用添加在数据标签中的标题和正文。Anand saga发布的答案是正确的
您需要在数据部分添加标题和正文。尽管通知负载是从后端节点API发送的,但在恢复和启动时它将为空
下面是正在解决的有效载荷颤振恢复示例:
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"}}
恢复时{通知:{},数据:{图像:https://ibin.co/2t1lLdpfS06F.png,google.original_priority:normal,google.sent_time:15773898934347,google.delivered_priority:normal,body:“自定义body”,类型:OrderDetail,title:“自定义title”,点击动作:颤振通知,点击,谷歌。消息id:0:157738935352165%dfef845edfef845e,折叠键:,谷歌。ttl:2419200,发件人: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);
},
);
firebaseMessaging.configure(
onMessage:(映射消息)异步{
打印('on message${json.encode(message['data']['title']]))});
重定向屏幕加载(消息);
},
onResume:(映射消息)异步{
firebaseMessaging.onTokenRefresh;
打印('在简历上$message');
重定向屏幕加载(消息);
},
onLaunch:(映射消息)异步{
firebaseMessaging.onTokenRefresh;
//等待API.updateUserApiToGetFCMKey();
打印('on launch$message');
重定向屏幕加载(消息);
},
);
在redirectScreenOnLoad(字符串消息)中,我正在检查输入负载并重定向到不同的屏幕如果您的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"));
}
}
别忘了把它加在你的手上
android:name=“.Application”
在本节的firebase\u消息包文档中,他们说您需要将单击\u操作:颤振\u通知\u单击
作为“自定义数据”要调用的onResume
和Onlaunch
方法的服务器端post请求中的键值对
例如,我使用此处向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);
FCM故障排除的另一个需要添加的内容是在您的onMessage
处理中
首先,在on中
Complete guide to handle firebase messaging:
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.
);