9

I am using Firebase Push Notifications and I want to execute some of my code when onBackgroundMessage is triggered. It actually gets triggered because I print in console, but I tried to use several plugins and no luck. I get error every time something like (Unhandled Exception: MissingPluginException(No implementation found for method play on channel flutter_ringtone_player)). I believe this is because there is no context of application in background state of application, but what is this function good for then and what can I actually do in it?

I would like to play sound when onBackgroundMessage is triggered.

    super.initState();

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
      },
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
      },
    );

static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {        
  FlutterRingtonePlayer.play(
    android: AndroidSounds.notification,
    ios: IosSounds.glass,
    looping: true, // Android only - API >= 28
    volume: 0.8, // Android only - API >= 28
    asAlarm: true, // Android only - all APIs
  );

    print("background message executed");

  return null;
}
PoorMillionaire
  • 347
  • 1
  • 2
  • 8

3 Answers3

4

Try registering the plugins that you need to use in myBackgroundMessageHandler in your Android's Application class. Here is an example of my Application.kt:

class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
    super.onCreate()
    FlutterFirebaseMessagingService.setPluginRegistrant(this)
}

override fun registerWith(registry: PluginRegistry?) {
    PathProviderPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"))
    FlutterLocalNotificationsPlugin.registerWith(registry?.registrarFor("com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin"))
    FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
}
}
Mark
  • 1,130
  • 3
  • 17
  • 32
  • Where can I get this "name" - io.flutter.plugins.pathprovider.PathProviderPlugin for https://pub.dev/packages/audioplayers. I can't get this work. I tried io.flutter.plugins.audioplayers.AudioplayersPlugin, but no luck. – PoorMillionaire Apr 08 '20 at 12:30
  • Look in your GeneratedPluginRegistrant.java file. You should be able to find the entire package path in there. – Mark Apr 08 '20 at 13:48
  • I actually used another plugin: https://pub.dev/packages/assets_audio_player and it's working! Thank you so much! I believe that with the right package path audioplayers would work too. Awesome. I will paste my code in the answer. – PoorMillionaire Apr 08 '20 at 13:59
4

Here is a working code. When device receive push notification (Firebase), onBackgroundMessage is executed and custom sound is played even if the app is closed.

main.dart

static Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async {        
    final assetsAudioPlayer = AssetsAudioPlayer();

    assetsAudioPlayer.open(
        Audio("assets/audio/alarm.mp3"),
    );

    print("sound played");

    return null;
  }

  void initState() {
    super.initState();

    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage: $message");
      },
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
      },
      onBackgroundMessage: myBackgroundMessageHandler
    );
  }

Application.kt

import com.github.florent37.assetsaudioplayer.AssetsAudioPlayerPlugin

class Application : FlutterApplication(), PluginRegistrantCallback {
    override fun onCreate() {
        super.onCreate()
        FlutterFirebaseMessagingService.setPluginRegistrant(this)
    }   

    override fun registerWith(registry: PluginRegistry) {
        AssetsAudioPlayerPlugin.registerWith(registry?.registrarFor("com.github.florent37.assetsaudioplayer"))

        FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
    }
}
PoorMillionaire
  • 347
  • 1
  • 2
  • 8
3

To avoid such issues, I suggest remaining uptodate with the latest version of firebase_messaging on flutter (flutter version >= 1.12). As stated in the official doc:

If you are using Flutter Android Embedding V2 (Flutter Version >= 1.12) then no additional integration steps are required for Android.

In order to proceed using firebase in this case, follow the following steps:

  1. In your pubspec.yaml file, add these two dependencies:

    firebase_core: ^0.7.0
    firebase_messaging: ^8.0.0-dev.15  
    
  2. Run flutter pub get

Code samples:

Before using any firebase service, you need to use await Firebase.initializeApp(); as stated here

Code sample to receive Firebase Push when the app is in the foreground:

FirebaseMessaging _messaging;
await Firebase.initializeApp();
  _messaging = FirebaseMessaging.instance;
   //App is in the foreground

  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print('Got a message, app is in the foreground!');
    print('Message data: ${message.data}');

    if (message.notification != null) {
      print('Message also contained a notification: ${message.notification}');
    }
  });

Code Sample App is in the background/Termintated:

You need to define a top-level function (a function that is outside the class). The latter will be called when a message occurs and the app is in the background: According to the doc, it should be as following:

Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message,
) async {
   await Firebase.initializeApp();
   print('onBackgroundMessage received: $message');
  
 }

Then, the above mentioned will be used here:

 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
Fahima Mokhtari
  • 1,691
  • 2
  • 16
  • 30