Flutterfire: [Firebase Messaging] onBackgroundMessage Never Called

Created on 11 Sep 2019  路  22Comments  路  Source: FirebaseExtended/flutterfire

I followed the tutorial on how to add the library after adding everything works well except for onBackgroundMessage. It is never called and I get this error in the logs: "Fatal: failed to find callback".

crowd bug

Most helpful comment

Hi guys, same problem here...
Followed the docs and I'm getting nothing... The onBackgroundMessage event is not being called...
I tried also @Harishpenta implementation and I get nothing... No errors and the method is not called...
Any suggestions?
Thanks

I managed to get my app working and listening to onBackgroundMessage on Android (I just removed the notification object from my payload, leaving only the data object), but when I tested on iOS device, nothing happens, the app doesn't listen the onBackgroundMessage event as it did on Android... Any thoughts?

All 22 comments

i have same issue like that too

@Harishpenta Thanks! I think it works for toRawHandle problem. I changed backgroundCallback to static / global method. But now I run into another problem.

E/MethodChannel#plugins.flutter.io/firebase_messaging(26024): Failed to handle method call
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024): java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.Application android.app.Activity.getApplication()' on a null object reference
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at vn.hunghd.flutterdownloader.FlutterDownloaderPlugin.registerWith(FlutterDownloaderPlugin.java:68)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:38)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at com.example.myexample.Application.registerWith(Application.java:18)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.startBackgroundIsolate(FlutterFirebaseMessagingService.java:164)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.onMethodCall(FirebaseMessagingPlugin.java:133)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:656)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at android.os.MessageQueue.next(MessageQueue.java:325)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at android.app.ActivityThread.main(ActivityThread.java:6944)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
E/MethodChannel#plugins.flutter.io/firebase_messaging(26024):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
D/libGLESv2(26024): STS_GLApi : DTS, ODTC are not allowed for Package : com.example.myexample
E/flutter (26024): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Attempt to invoke virtual method 'android.app.Application android.app.Activity.getApplication()' on a null object reference, null)
E/flutter (26024): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:569:7)
E/flutter (26024): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:316:33)
E/flutter (26024): <asynchronous suspension>
E/flutter (26024): #2      FirebaseMessaging.configure (package:firebase_messaging/firebase_messaging.dart:118:16)
E/flutter (26024): #3      _AppState.initState (package:myexample/app.dart:108:24)
E/flutter (26024): #4      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4068:58)
E/flutter (26024): #5      ComponentElement.mount (package:flutter/src/widgets/framework.dart:3919:5)
E/flutter (26024): #6      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14)
E/flutter (26024): #7      Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12)
E/flutter (26024): #8      RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:998:16)
E/flutter (26024): #9      RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:969:5)
E/flutter (26024): #10     RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:915:17)
E/flutter (26024): #11     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2328:19)
E/flutter (26024): #12     RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:914:13)
E/flutter (26024): #13     WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:795:7)
E/flutter (26024): #14     runApp (package:flutter/src/widgets/binding.dart:845:7)
E/flutter (26024): #15     main (package:myexample/main.dart:21:3)
E/flutter (26024): #16     _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:229:25)
E/flutter (26024): #17     _rootRun (dart:async/zone.dart:1124:13)
E/flutter (26024): #18     _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter (26024): #19     _runZoned (dart:async/zone.dart:1516:10)
E/flutter (26024): #20     runZoned (dart:async/zone.dart:1500:12)
E/flutter (26024): #21     _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:221:5)
E/flutter (26024): #22     _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:305:19)
E/flutter (26024): #23     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)

could you show me your code how you have implemented.

@Harishpenta are you sure it work for background message?
can you send link your code github?
so if it work why flutter dev say it is bug???

@Harishpenta this is my implementation

java/com/example/myexample/Application.java

package com.example.myexample;

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;

public class Application extends FlutterApplication implements PluginRegistrantCallback {
    @Override
    public void onCreate() {
        super.onCreate();
        FlutterFirebaseMessagingService.setPluginRegistrant(this);
    }

    @Override
    public void registerWith(PluginRegistry registry) {
        GeneratedPluginRegistrant.registerWith(registry);
    }
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myexample">
<!-- Some Permission  -->
<application
        android:name=".Application"

main.dart

@override
initState(){
    super.initState();
   _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
        dynamic data = message['data'];
        if (data == null) return;
        String notificationType = data['notification_type'];

        if (notificationType != null ||
            notificationType.isEmpty ||
            notificationType == UIData.notificationForeground) {
        } else if (notificationType == UIData.notificationInAppDialog) {}
      },
      onBackgroundMessage: fcmBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
      },
      onResume: (Map<String, dynamic> message) async {
      },
    );

    _firebaseMessaging.getToken().then((String token) {
    });

    _firebaseMessaging.subscribeToTopic(UIData.generalTopic);
}

  static Future<dynamic> fcmBackgroundMessageHandler(
      Map<String, dynamic> message) {
    if (message.containsKey('data')) {
      // Handle data message
      final dynamic data = message['data'];
    }

    if (message.containsKey('notification')) {
      // Handle notification message
      final dynamic notification = message['notification'];
    }

    return null;
    // Or do other work.
  }

After changing onBackgroundMessage to static now I have the same problem as @samuelg123 .
Below are the logs:

E/MethodChannel#plugins.flutter.io/firebase_messaging: Failed to handle method call
java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.Application android.app.Activity.getApplication()' on a null object reference
at vn.hunghd.flutterdownloader.FlutterDownloaderPlugin.registerWith(FlutterDownloaderPlugin.java:68)
at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:57)
at com.casadevlimited.apps.tpp_flutter.Application.registerWith(Application.java:19)
at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.startBackgroundIsolate(FlutterFirebaseMessagingService.java:167)
at io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.onMethodCall(FirebaseMessagingPlugin.java:134)
at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:656)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:181)
at android.app.ActivityThread.main(ActivityThread.java:7045)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

@samuelg123 @nivla360 Background FlutterViews do not have an activity, the FlutterDownloaderPlugin assumes an activity is available which result in a crash when the plugin is registered by a background FlutterView.

Here is a PR with a fix https://github.com/fluttercommunity/flutter_downloader/pull/117

@herasymchuk okay, thanks. So how do I fix it?

this is how i have created a Notification Handler Class.
notification_handler.dart

  import 'dart:async';
  import 'dart:convert';
  import 'dart:io';
  import 'dart:math';

  import 'package:firebase_messaging/firebase_messaging.dart';
  import 'package:flutter/cupertino.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  import 'package:onlinetrading/utils/constants.dart';
  import 'package:onlinetrading/view/dashboard/dashboard.dart';
  import 'package:path_provider/path_provider.dart';
  import 'package:http/http.dart' as http;

  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      new FlutterLocalNotificationsPlugin();

  Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
    print("onBackgroundMessage: $message");
    _showBigPictureNotification(message);
    return Future<void>.value();
  }


  Future onSelectNotification(String payload) async {
    debugPrint("The Context is : " + contextMain.toString());
    if (payload != null) {
      await Navigator.push(
    contextMain,
    new MaterialPageRoute(builder: (context) => new Dashboard()),
      );
    }
  }

  class NotificationHandler {
    FirebaseMessaging _fcm = FirebaseMessaging();
    StreamSubscription iosSubscription;
    static final NotificationHandler _singleton =
    new NotificationHandler._internal();

    factory NotificationHandler() {
      return _singleton;
    }
    NotificationHandler._internal();

    initializeFcmNotification() async {
      var initializationSettingsAndroid =
      new AndroidInitializationSettings('ic_launcher');
      var initializationSettingsIOS = new IOSInitializationSettings(
      onDidReceiveLocalNotification: onDidReceiveLocalNotification);
      var initializationSettings = new InitializationSettings(
      initializationSettingsAndroid, initializationSettingsIOS);
      flutterLocalNotificationsPlugin.initialize(initializationSettings,
      onSelectNotification: onSelectNotification);

      if (Platform.isIOS) {
    iosSubscription = _fcm.onIosSettingsRegistered.listen((data) {
      // save the token  OR subscribe to a topic here
    });

    _fcm.requestNotificationPermissions(IosNotificationSettings());
      } else {
    _saveDeviceToken();
      }

      _fcm.configure(
    onMessage: (Map<String, dynamic> message) async {         
      showDialog(
        context: contextMain,
        builder: (BuildContext context) {
          return AlertDialog(
            title: new Text(message['rows'][0]['data'][4]),
            content: new Text(message['rows'][0]['data'][3]),
            actions: <Widget>[
              new FlatButton(
                child: new Text("Close"),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        },
      );
    },
    onBackgroundMessage:
        TargetPlatform.iOS == 'ios' ? null : myBackgroundMessageHandler,
    onLaunch: (Map<String, dynamic> message) async {
      print("onLaunch: $message");
    },
    onResume: (Map<String, dynamic> message) async {
      print("onResume: $message");
    },
      );
    }

    /// Get the token, save it to the database for current user
    _saveDeviceToken() async {
      String fcmToken = await _fcm.getToken();
      print("FCM_TOKEN: $fcmToken");
    }

    Future<void> onDidReceiveLocalNotification(
    int id, String title, String body, String payload) async {
      // display a dialog with the notification details, tap ok to go to another page
    }
  }

And then i have just called it as below in my StateFullWidget for initialization.

   @override
    void initState() {
      super.initState();
      new NotificationHandler().initializeFcmNotification();
    }

@herasymchuk okay, thanks. So how do I fix it?

As a temporary solution, you can fetch plugin from PR branch until it will be merged to master.
In your pubspec.yaml update flutter_downloader dependency:

flutter_downloader:
    git:
      url: git://github.com/Mahfoud047/flutter_downloader.git
      ref: fix-uncompatibility-with-background-registeration-context

@herasymchuk @Harishpenta Thank you very much!

I end up using your fix @herasymchuk and combine it with @Harishpenta implementation. And it works perfectly!

Thanks a lot guys!!
I implemented both methods as @samuelg123 did and it worked. I'm truly grateful.

write it in your main.dart, below is my code snippet

Future myBackgroundMessageHandler(Map message) async{
print(message);
}

main() async {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
_firebaseMessaging.configure(
onMessage: (Map message) async {
print("onMessage: $message");
},
onBackgroundMessage: myBackgroundMessageHandler,
onLaunch: (Map message) async {
print("onLaunch: $message");
},
onResume: (Map message) async {
print("onResume: $message");
},);

runApp(App());
});

Hi @nivla360
I see there's an open issue addressing the case you described.
Please follow up on that issue,
I'm closing the current one as duplicate.
If you disagree please write in the comments
and I will reopen it.
Thank you

陌f you didn't add Application.java on your project. You can see this problem. I solved this way

@Harishpenta

How did you get the mainContext in the notification_handler singleton? For Navigator one needs the context and there is a mainContext I see you are using but I couldn't see it in the code you posted as to how you got the mainContext. Many thanks.

this is how i have created a Notification Handler Class.
notification_handler.dart

  import 'dart:async';
  import 'dart:convert';
  import 'dart:io';
  import 'dart:math';

  import 'package:firebase_messaging/firebase_messaging.dart';
  import 'package:flutter/cupertino.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  import 'package:onlinetrading/utils/constants.dart';
  import 'package:onlinetrading/view/dashboard/dashboard.dart';
  import 'package:path_provider/path_provider.dart';
  import 'package:http/http.dart' as http;

  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      new FlutterLocalNotificationsPlugin();

  Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {
    print("onBackgroundMessage: $message");
    _showBigPictureNotification(message);
    return Future<void>.value();
  }


  Future onSelectNotification(String payload) async {
    debugPrint("The Context is : " + contextMain.toString());
    if (payload != null) {
      await Navigator.push(
  contextMain,
  new MaterialPageRoute(builder: (context) => new Dashboard()),
      );
    }
  }

  class NotificationHandler {
    FirebaseMessaging _fcm = FirebaseMessaging();
    StreamSubscription iosSubscription;
    static final NotificationHandler _singleton =
  new NotificationHandler._internal();

    factory NotificationHandler() {
      return _singleton;
    }
    NotificationHandler._internal();

    initializeFcmNotification() async {
      var initializationSettingsAndroid =
    new AndroidInitializationSettings('ic_launcher');
      var initializationSettingsIOS = new IOSInitializationSettings(
    onDidReceiveLocalNotification: onDidReceiveLocalNotification);
      var initializationSettings = new InitializationSettings(
    initializationSettingsAndroid, initializationSettingsIOS);
      flutterLocalNotificationsPlugin.initialize(initializationSettings,
    onSelectNotification: onSelectNotification);

      if (Platform.isIOS) {
  iosSubscription = _fcm.onIosSettingsRegistered.listen((data) {
    // save the token  OR subscribe to a topic here
  });

  _fcm.requestNotificationPermissions(IosNotificationSettings());
      } else {
  _saveDeviceToken();
      }

      _fcm.configure(
  onMessage: (Map<String, dynamic> message) async {         
    showDialog(
      context: contextMain,
      builder: (BuildContext context) {
        return AlertDialog(
          title: new Text(message['rows'][0]['data'][4]),
          content: new Text(message['rows'][0]['data'][3]),
          actions: <Widget>[
            new FlatButton(
              child: new Text("Close"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  },
  onBackgroundMessage:
      TargetPlatform.iOS == 'ios' ? null : myBackgroundMessageHandler,
  onLaunch: (Map<String, dynamic> message) async {
    print("onLaunch: $message");
  },
  onResume: (Map<String, dynamic> message) async {
    print("onResume: $message");
  },
      );
    }

    /// Get the token, save it to the database for current user
    _saveDeviceToken() async {
      String fcmToken = await _fcm.getToken();
      print("FCM_TOKEN: $fcmToken");
    }

    Future<void> onDidReceiveLocalNotification(
  int id, String title, String body, String payload) async {
      // display a dialog with the notification details, tap ok to go to another page
    }
  }

And then i have just called it as below in my StateFullWidget for initialization.

   @override
    void initState() {
      super.initState();
      new NotificationHandler().initializeFcmNotification();
    }

Hi guys, same problem here...
Followed the docs and I'm getting nothing... The onBackgroundMessage event is not being called...
I tried also @Harishpenta implementation and I get nothing... No errors and the method is not called...
Any suggestions?
Thanks

Hi guys, same problem here...
Followed the docs and I'm getting nothing... The onBackgroundMessage event is not being called...
I tried also @Harishpenta implementation and I get nothing... No errors and the method is not called...
Any suggestions?
Thanks

I managed to get my app working and listening to onBackgroundMessage on Android (I just removed the notification object from my payload, leaving only the data object), but when I tested on iOS device, nothing happens, the app doesn't listen the onBackgroundMessage event as it did on Android... Any thoughts?

@gustavoergalves Please make sure you have allowed the background fetch mode in ios Capabilities if you have signed with a developer account.

@duncwillz will the onBackgroundMessage be called on iOS when the app is Terminated.
If yes, then will I be able to show an alert dialogue that notification is received?

Hi guys, same problem here...
Followed the docs and I'm getting nothing... The onBackgroundMessage event is not being called...
I tried also @Harishpenta implementation and I get nothing... No errors and the method is not called...
Any suggestions?
Thanks

I managed to get my app working and listening to onBackgroundMessage on Android (I just removed the notification object from my payload, leaving only the data object), but when I tested on iOS device, nothing happens, the app doesn't listen the onBackgroundMessage event as it did on Android... Any thoughts?

You really saved my day :))

Was this page helpful?
0 / 5 - 0 ratings