Flutter:不能在onBackgroundMessage中使用任何插件

时间:2020-04-06 19:32:23

标签: firebase flutter firebase-cloud-messaging

我正在使用Firebase推送通知,并且希望在触发onBackgroundMessage时执行一些代码。它实际上是由于在控制台中打印而触发的,但是我尝试使用多个插件,但没有运气。每当出现类似(未处理的异常:MissingPluginException(在通道flutter_ringtone_player上未找到方法播放的实现))时,我都会收到错误。我相信这是因为在应用程序的后台状态中没有应用程序的上下文,但是此功能当时对我有什么好处,我该怎么做呢?

我想在触发onBackgroundMessage时播放声音。

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

3 个答案:

答案 0 :(得分:4)

为了避免此类问题,我建议保持最新版本的 firebase_messaging on flutter(flutter 版本 >= 1.12)。如the official doc中所述:

<块引用>

如果您使用的是 Flutter Android Embedding V2(Flutter 版本 >= 1.12) 那么 Android 不需要额外的集成步骤。

为了在这种情况下继续使用 firebase,请按照以下步骤操作:

  1. 在您的 pubspec.yaml 文件中,添加以下两个依赖项:

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

代码示例:

在使用任何 firebase 服务之前,您需要按照说明使用 await Firebase.initializeApp(); here

当应用在前台时接收 Firebase 推送的代码示例:

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

代码示例应用程序在后台/终止

你需要定义一个顶级函数(一个在类之外的函数)。后者将在消息发生且应用程序处于后台时调用: 根据{{​​3}},它应该如下:

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

然后,上面提到的将在这里使用:

 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

答案 1 :(得分:3)

这是一个工作代码。设备收到推送通知(Firebase)时,即使关闭了应用程序,也会执行onBackgroundMessage并播放自定义声音。

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

答案 2 :(得分:2)

尝试在Android的Application类中的myBackgroundMessageHandler中注册需要使用的插件。这是我的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)
}
}