26

I'm trying to use FCM messaging and keep getting this error.

E/FlutterFcmService( 3684): Fatal: failed to find callback

Below is the code I've used to setup.

  static Future<void> messagePiper(
      Map<String, dynamic> message,
      FilteredMap<String, ChatMessage> globalChatEntryMap,
      FilteredMap<String, ChatMessage> gameChatEntryMap,
      Subject<List<ChatMessage>> globalChatSubject,
      Subject<List<ChatMessage>> gameChatSubject,
      Map<String, Player> _playerMap) async {
    final Map<String, dynamic> data = message['data'];
    if (data.containsKey('name')) {
      final msg = ChatMessage.fromMap(data);
      globalChatEntryMap.putIfAbsent(msg.id, () => msg);
      globalChatSubject.add(globalChatEntryMap.values.toList());
    } else {
      final msg = GameChatMessage.fromMap(data);

      final chat = ChatMessage.fromGlobalChatMessage(
        msg,
        _playerMap[msg.pId].name,
        _playerMap[msg.pId].imageUrl,
      );

      print('chat: $chat');
      gameChatEntryMap.putIfAbsent(msg.id, () => chat);
      print('_gameChatEntryMap : $gameChatEntryMap');
      gameChatSubject.add(gameChatEntryMap.values.toList());
    }

    return Future<void>.value();
  }

is the callback passed in to FirebaseMessaging configuration.

  final FirebaseMessaging _fm = FirebaseMessaging();

  @override
  void initState() {

   _fm.configure(
        onMessage: (Map<String, dynamic> message) async {
          print('onMessagee : $message');
          return Utils.messagePiper(
              message,
              _globalChatEntryMap,
              _gameChatEntryMap,
              _globalChatSubject,
              _gameChatSubject,
              _playerMap);
        },
        onLaunch: (Map<String, dynamic> message) async {
          print('onLaunch : $message');
          return Utils.messagePiper(
              message,
              _globalChatEntryMap,
              _gameChatEntryMap,
              _globalChatSubject,
              _gameChatSubject,
              _playerMap);
          ;
        },
        onResume: (Map<String, dynamic> message) async {
          print('onResume : $message');
          return Utils.messagePiper(
              message,
              _globalChatEntryMap,
              _gameChatEntryMap,
              _globalChatSubject,
              _gameChatSubject,
              _playerMap);
          ;
        },
        onBackgroundMessage: null);
....

Java configuration file

package io.flutter.plugins;

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);
    }
}

dependency versions

  random_string: 0.0.2
  firebase_auth: ^0.14.0+5
  firebase_database: ^3.0.7
  provider: 3.0.0
  rxdart: ^0.22.2
  collection: ^1.14.11
  audioplayers: ^0.13.2
  firebase_admob: ^0.5.5
  connectivity: ^0.4.4
  firebase_messaging: ^5.1.6 # tried with several different versions

I tried with several firebase_messaging versions but couldn't find a fix.

Appreciate any help to solve this issue.

tharindu_DG
  • 8,900
  • 6
  • 52
  • 64
  • How come you have a custom Application class but no `onBackgroundMessage` callback? You only need the custom java file if you want to use background messaging. – DF_ Sep 29 '19 at 21:03
  • 1
    Java file? MainActivity.kt importing it? ``` import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService ``` and put it? ``` flutterEngine.plugins.add(FlutterFirebaseMessagingService()) ``` in configureFlutterEngine? – shinriyo Aug 17 '20 at 02:02

5 Answers5

31

This error message is coming from startBackgroundIsolate which is used for allowing handling background messages. If you don't want to handle background messages then you can safely ignore this error message. Otherwise, you need to set up a callback for handling background messages as described here

If your callback is not executed when clicking on the notification then it's because you didn't set click_action property of the message to FLUTTER_NOTIFICATION_CLICK

Taufiq Rahman
  • 5,600
  • 2
  • 36
  • 44
Morad
  • 2,761
  • 21
  • 29
  • 5
    I am sending the ```click_action ```: ```FLUTTER_NOTIFICATION_CLICK``` in the notification still getting an error in onMessage callback as: ``` Fatal: failed to find callback``` – Dhaval Kansara Jul 21 '20 at 11:02
  • 2
    Me too Android only failed to find callback – shinriyo Aug 17 '20 at 02:32
  • @shinriyo as said you should ignore this "failed to find callback" error message if you do not intend to handle background messages. If you want to get rid of this error message then you need to setup a callback for handling background messages – Morad Aug 30 '20 at 18:14
4

Are you sending FCM using the web, not FCM console? make sure the post request is correct on your backend. I'm using Laravel

$response = Http::withHeaders([
            'Content-Type' => 'application/json',
            'Authorization'=> 'key='. $token,
        ])->post($url, [
            'notification' => [
                'body' => $request->summary,
                'title' => $request->title,
                'image' => request()->getHttpHost().$path,
                
            ],
            'priority'=> 'high',
            'data' => [
                'click_action'=> 'FLUTTER_NOTIFICATION_CLICK',
                
                'status'=> 'done',
                
            ],
            'to' => '/topics/all'
        ]);
James Christian Kaguo
  • 1,251
  • 15
  • 14
3

You should declare a backgroundMessageHandler function that is outside a class or as a static function, in order to be reached from outside, and then you pass this function to fbm.configure:

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) {
  print('on background $message');
}

fbm.configure(
      onMessage: (msg) {
        print(msg);
        return;
      },
      onLaunch: (msg) {
        print(msg);
        return;
      },
      onResume: (msg) {
        print(msg);
        return;
      },
      onBackgroundMessage: myBackgroundMessageHandler
);

Also open your_project_folder/android/app/source/AndroidManifest.xml and paste this XML code after existing intent-filter code of your main Activity:

<intent-filter>
    <action android:name="FLUTTER_NOTIFICATION_CLICK" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

The result will be similar to the following code:

<activity android:name=".MainActivity" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
</activity>
Rafael Bartz
  • 308
  • 2
  • 10
2

In Application class use the below code

previously it was GeneratedPluginRegistrant.registerWith(registry);,

replace it with FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));

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.FirebaseMessagingPlugin;
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){
        FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
    }


}
Vettiyanakan
  • 7,957
  • 6
  • 37
  • 55
0

When I was trying to send a notification from the firebase console just to test my app receives notifications, I also encountered the same error. Make sure you kill the app on your emulator so it is not running in the background. And now try sending a notification from the firebase console, wait for a couple of seconds and you should see it. This worked for me.

Anita
  • 131
  • 1
  • 6