在 iOS 模拟器中收到 Firebase FCM 通知,但在真正的 iOS 设备上作为 GCM(?) 在 flutter 应用程序中收到
Firebase FCM notification received in iOS simulator but as GCM(?) on real iOS device in flutter app
编辑:根据 Firebase 支持
,它应该看起来像在设备日志中显示的那样
我正在通过 FCM 将推送通知添加到我的 Flutter 应用程序,但是 iOS 模拟器与我的 iPhone 5s 上的消息格式非常不同。
从 Firebase 控制台接收到 active/opened 应用程序的推送通知时。
问题:我需要做什么来确保真实设备以正确的格式接收消息?
从模拟器登录(iPhone XR,12.2)(在官方代码示例中看起来像):
onMessage: {
from: 123000000000,
collapse_key: com.mydomainnamehere,
notification: {
body: Lorem ipsum,
title: Title,
e: 1,
tag: campaign_collapse_key_9876543210011223344
}
}
从真实设备登录(iPhone 5s,12.2)(在线找不到任何参考):
onMessage: {
google.c.a.c_l: notif_name,
google.c.a.e: 1,
aps: {
alert: {
title: Title,
body: Lorem ipsum
}
},
gcm.n.e: 1,
google.c.a.c_id: 9876543210011223344,
google.c.a.udt: 0,
gcm.message_id: 1234567800998877,
google.c.a.ts: 1234567800
}
通知从 Firebase 控制台发送到所有设备,日志来自同一个通知(但我匿名了 id)。
设备和模拟器 运行 来自 Android Studio 的相同 Flutter 代码,同时。
我的 pubspec.yaml 部分涉及 FCM
firebase_core: ^0.4.0+1
firebase_auth: 0.11.1
cloud_firestore: ^0.11.0+2
firestore_ui: ^1.4.0
firebase_messaging: ^5.0.2
软件和 SDK 版本
Flutter Channel 开发者,v1.8.4,
Mac OS X 10.14.5,
Android SDK 版本 28.0.3,
Xcode 10.2.1,
Android Studio 版本 3.4
Flutter 消息处理代码
void initState() {
super.initState();
if (Platform.isIOS) {
iosSubscription = _fcm.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
print("FCM settings received: $settings");
});
_fcm.requestNotificationPermissions(IosNotificationSettings());
}
_fcm.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
);
getFcmToken();
}
void getFcmToken() async {
var token = await FirebaseMessaging().getToken();
print("Token $token");
}
我原以为 JSON 格式在模拟器和真实设备上是相同的。但真实设备甚至没有收到所有通知。
根据 Firebase 支持,我们应该无法在模拟器中获取推送通知,他们说上面的 gcm-format 确实是正确的。
解决方案是始终使用上一个问题的答案中所述的键值对
对于那些仍然为此苦苦挣扎的人来说,似乎有一个替代解决方案。
虽然数据的结构在各种条件下可能不同(iOS/Android 或 Real device/Simulator),但无论嵌套多深,数据的这些重要部分的键名称都被认为是唯一的:“title " 和 "body"。因此,提取那些 'title' 和 'body' 条目的值可能会解决问题。
//get title value from the message load (whether data or push)
String _title = _findFirstKeyValue(message, 'title');
下面是一个递归函数,用于从消息 Map 中获取第一个匹配条目。
String _findFirstKeyValue(Map data, String targetKey) {
for (final k in data.keys) {
final v = data[k];
if (v is Map) { // go deeper if the value is still a kind of Map
final String _temp = _findFirstKeyValue(v, targetKey);
if (_temp != '') return _temp;
} else { // when the value is primitive Key-Value pair
if (k.toString().toLowerCase() == targetKey.toLowerCase()) {
return v.toString();
}
}
}
return '';
}
请注意,如果您使用 data.forEach
而不是普通的 for loop
,return
将不会被触发。
编辑:根据 Firebase 支持
,它应该看起来像在设备日志中显示的那样我正在通过 FCM 将推送通知添加到我的 Flutter 应用程序,但是 iOS 模拟器与我的 iPhone 5s 上的消息格式非常不同。 从 Firebase 控制台接收到 active/opened 应用程序的推送通知时。
问题:我需要做什么来确保真实设备以正确的格式接收消息?
从模拟器登录(iPhone XR,12.2)(在官方代码示例中看起来像):
onMessage: {
from: 123000000000,
collapse_key: com.mydomainnamehere,
notification: {
body: Lorem ipsum,
title: Title,
e: 1,
tag: campaign_collapse_key_9876543210011223344
}
}
从真实设备登录(iPhone 5s,12.2)(在线找不到任何参考):
onMessage: {
google.c.a.c_l: notif_name,
google.c.a.e: 1,
aps: {
alert: {
title: Title,
body: Lorem ipsum
}
},
gcm.n.e: 1,
google.c.a.c_id: 9876543210011223344,
google.c.a.udt: 0,
gcm.message_id: 1234567800998877,
google.c.a.ts: 1234567800
}
通知从 Firebase 控制台发送到所有设备,日志来自同一个通知(但我匿名了 id)。
设备和模拟器 运行 来自 Android Studio 的相同 Flutter 代码,同时。
我的 pubspec.yaml 部分涉及 FCM
firebase_core: ^0.4.0+1
firebase_auth: 0.11.1
cloud_firestore: ^0.11.0+2
firestore_ui: ^1.4.0
firebase_messaging: ^5.0.2
软件和 SDK 版本
Flutter Channel 开发者,v1.8.4, Mac OS X 10.14.5, Android SDK 版本 28.0.3, Xcode 10.2.1, Android Studio 版本 3.4
Flutter 消息处理代码
void initState() {
super.initState();
if (Platform.isIOS) {
iosSubscription = _fcm.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
print("FCM settings received: $settings");
});
_fcm.requestNotificationPermissions(IosNotificationSettings());
}
_fcm.configure(
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
},
);
getFcmToken();
}
void getFcmToken() async {
var token = await FirebaseMessaging().getToken();
print("Token $token");
}
我原以为 JSON 格式在模拟器和真实设备上是相同的。但真实设备甚至没有收到所有通知。
根据 Firebase 支持,我们应该无法在模拟器中获取推送通知,他们说上面的 gcm-format 确实是正确的。
解决方案是始终使用上一个问题的答案中所述的键值对
对于那些仍然为此苦苦挣扎的人来说,似乎有一个替代解决方案。 虽然数据的结构在各种条件下可能不同(iOS/Android 或 Real device/Simulator),但无论嵌套多深,数据的这些重要部分的键名称都被认为是唯一的:“title " 和 "body"。因此,提取那些 'title' 和 'body' 条目的值可能会解决问题。
//get title value from the message load (whether data or push)
String _title = _findFirstKeyValue(message, 'title');
下面是一个递归函数,用于从消息 Map 中获取第一个匹配条目。
String _findFirstKeyValue(Map data, String targetKey) {
for (final k in data.keys) {
final v = data[k];
if (v is Map) { // go deeper if the value is still a kind of Map
final String _temp = _findFirstKeyValue(v, targetKey);
if (_temp != '') return _temp;
} else { // when the value is primitive Key-Value pair
if (k.toString().toLowerCase() == targetKey.toLowerCase()) {
return v.toString();
}
}
}
return '';
}
请注意,如果您使用 data.forEach
而不是普通的 for loop
,return
将不会被触发。