Firebase FCM notification received in iOS simulator but as GCM(?) on real iOS device in flutter app
Solution 1
According to Firebase support, we should not be able to get push notifications in the simulator, and they say that the gcm-format above is indeed the correct one.
The solution is to always use key-value pairs as stated in the answer to this previous question FCM - Get Message Label
Solution 2
For those who still struggle with this, there seems an alternative solution. While the structure of the data can be different in various conditions (iOS/Android or Real device/Simulator), the key names of those essential parts of the data are considered to be unique no matter how deeply nested: "title" and "body". Therefore, extracting the values of those 'title' and 'body' entries might solve the problem.
//get title value from the message load (whether data or push)
String _title = _findFirstKeyValue(message, 'title');
The following is a recursive function to get the first matching entry from the message 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 '';
}
Note that return
will not be fired if you use data.forEach
rather than ordinary for loop
.
Jonas357
Doing innovative stuff leads to programming in all different kinds of languages.
Updated on December 13, 2022Comments
-
Jonas357 over 1 year
edit: it is supposed to look like it does on the device log, according to Firebase support
I am adding push notifications via FCM to my Flutter app, but the message format is very different on the iOS Simulator vs. my iPhone 5s. When receiving a push notification from the Firebase console to an active/opened app.
Problem: What do I need to do to make sure the real device receives the message in the correct format?
Log from Simulator (iPhone XR, 12.2) (looks like in the official code examples):onMessage: { from: 123000000000, collapse_key: com.mydomainnamehere, notification: { body: Lorem ipsum, title: Title, e: 1, tag: campaign_collapse_key_9876543210011223344 } }
Log from real device (iPhone 5s, 12.2) (can't find any references online to this):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 }
The notification is sent from the Firebase console to all devices, the logs are taken from the same notification (but I anonymized the id's).The Device and Simulator is running the same Flutter code from Android Studio, at the same time.
Parts of my pubspec.yaml that refers to 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
Software and SDK Versions
Flutter Channel dev, v1.8.4, Mac OS X 10.14.5, Android SDK version 28.0.3, Xcode 10.2.1, Android Studio version 3.4
Flutter message-handling code
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"); }
I was expecting that the JSON format would be the same on both the simulator and a real device. But the real device isn't even receiving all of the notification.