Solvedflutterfire Unable to use onBackgroundMessage in Firebase Cloud Messaging
βοΈAccepted Answer
Finally I got something working! I ended up using a named ReceivePort.
Here is what I did in main.dart:
final ReceivePort backgroundMessageport = ReceivePort();
const String backgroundMessageIsolateName = 'fcm_background_msg_isolate';
Future<dynamic> backgroundMessageHandler(Map<String, dynamic> message) async {
if (message.containsKey('data')) {
final port = IsolateNameServer.lookupPortByName(backgroundMessageIsolateName);
port.send(message);
}
}
void backgroundMessagePortHandler(message) {
final dynamic data = message['data'];
// Here I can access and update my top-level variables.
}
void main() {
...
IsolateNameServer.registerPortWithName(
backgroundMessageport.sendPort,
backgroundMessageIsolateName,
);
backgroundMessageport.listen(backgroundMessagePortHandler);
runApp(...)
}
Not sure if this violates Flutter or/and the isolate pattern and I would be happy to get input on this!
Other Answers:
@dvdlg Hi, i had found a solution for this issue yesterday... You should know that backgroundMessage Handler Method handle only Data message, this mean your message should not the message that your sending should have this structure : {
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
You should not put notification in it
@mostafa5731 , thank you very much for your answer, but unfortunately, it didn't work. When I tried to follow the steps in the link that you sent I got:
ERROR: MissingPluginException(No implementation found for method show on channel dexterous.com/flutter/local_notifications)moreover, this solution doesn't seem to answer my question. I want to display to the user how many messages he has got so far. For this I need to somehow change the app's state (change a global variable or the disk memory or anything), but it seems that background code cannot handle such thing.
I would be fine with onResume (without onBackgroundMessage) if it could be triggered when the user resumes to the app without tapping the notification.
class YourApplication : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
override fun registerWith(registry: PluginRegistry) {
CustomPluginRegistrant.registerWith(registry)
}
}
class CustomPluginRegistrant {
companion object {
fun registerWith(registry: PluginRegistry) {
if (alreadyRegisteredWith(registry)) {
return
}
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
FlutterLocalNotificationsPlugin.registerWith(registry.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"));
}
fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
val key: String = FirebaseCloudMessagingPluginRegistrant::class.java.getCanonicalName()
if (registry.hasPlugin(key)) {
return true
}
registry.registrarFor(key)
return false
}
}
}
I am trying to implement an app with notifications. I followed the official instructions of firebase_messaging (https://pub.dev/packages/firebase_messaging), and everything worked as promissed, but there is something I don't understand. I was able to trigger onMessage, onLaunch and onResume and make the UI respond properly (showing the user the recieved message). But when onBackgroundMessage is triggered, I can only print the message to the debugging console. I looked all over the internet, but it seems like that's how all discussions end. What can I do inside onBackgroundMessage? I failed to find any way to show to the user that the message had been recieved. I tried to navigate using a global navigator key but navigatorKey.currentState is null while running in background. I tried to update a provider, but it was also null. I even tried to update a global variable but it was the old value again when the app resumed to foreground. Could anyone please publish code example in which onBackgroundMessage has any impact on the user? (not only printing to the console).
The reason that I really want to use onBackgroundMessage is because when I get the notification while running in background, onResume and onLaunch are triggered only if I click the notification. If I click the app icon, the notification stays and nothing is triggered. I have no way to tell the user about the notification. If someone finds a way to read notifications that the user didn't click yet, that would help even more.
This is my code. When pressing button 1, a notification is sent after a delay of 5 seconds (to let the user time to put the app in background). When pressing button 2, a data message is sent.
Uppon recieving the message the three counters are incremented. But in some cases nothing happens.
expected result
In all scenarios all three counters should increment.
Actual result
In case the app was running in background while the message was sent, after resuming to the app nothing happend (both with buttom 1 and 2).