Reputation: 377
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;
}
Upvotes: 11
Views: 13784
Reputation: 2062
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:
In your pubspec.yaml file, add these two dependencies:
firebase_core: ^0.7.0
firebase_messaging: ^8.0.0-dev.15
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);
Upvotes: 3
Reputation: 377
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)
}
}
Upvotes: 4
Reputation: 1170
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)
}
}
Upvotes: 4