单击 FCM 通知时,Flutter Notification 挂起的意图被取消

Posted

技术标签:

【中文标题】单击 FCM 通知时,Flutter Notification 挂起的意图被取消【英文标题】:Flutter Notification pending intent canceled when clicked on FCM notification 【发布时间】:2021-12-11 19:29:54 【问题描述】:

当我在应用程序处于后台时收到来自firebase_messaging 的通知时,单击它会在控制台Notification pending intent canceled 中记录此错误,而不是打开应用程序。什么都没有发生

请注意,我在这个项目中使用flutter 1.22..6,所以我不得不使用旧版本的firebase_messageing,即7.0.3

我的 AndroidManifest.xml 中有这些行:

<!-- Note i have changed MainActitvy to Application based on documutions -->
    <application
        android:name=".Application" 
        android:label="DR Vendor"
        android:requestLegacyExternalStorage="true"
        android:usesCleartextTraffic="true"
        android:icon="@mipmap/launcher_icon">
       ....

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

我有 Application.java 就像:

package Here I have my package name;

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
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) 
        FirebaseCloudMessagingPluginRegistrant.registerWith(registry);
    



并将此文件添加到同一文件夹中FirebaseCloudMessagingPluginRegistrant.java

package my bundle name here;

import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;

public final class FirebaseCloudMessagingPluginRegistrant 
    public static void registerWith(PluginRegistry registry) 
        if (alreadyRegisteredWith(registry)) 
            return;
        
        FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
    

    private static boolean alreadyRegisteredWith(PluginRegistry registry) 
        final String key = FirebaseCloudMessagingPluginRegistrant.class.getCanonicalName();
        if (registry.hasPlugin(key)) 
            return true;
        
        registry.registrarFor(key);
        return false;
    


下面是我如何将后台处理程序方法添加为静态***方法

ma​​in.dart

Future<dynamic> myBackgroundMessageHandler(Map<String, dynamic> message) async 
  if (message.containsKey('data')) 
    // Handle data message
    final dynamic data = message['data'];
  

  if (message.containsKey('notification')) 
    // Handle notification message
    final dynamic notification = message['notification'];
    print("got notification");
    print(message);
  
  print("reached here");
  // Or do other work.




Future<void> main() async 
....
  await Firebase.initializeApp();
  PushNotificationsManager().init();
...


这就是我在main.dart 中调用PushNotificationsManager().init(); 时初始化FCM 的方式

  Future<void> init() async 
    if (!_initialized) 
      // For ios request permission first.
      _firebaseMessaging.requestNotificationPermissions();
      _firebaseMessaging.configure();
      var initializationSettingsAndroid =
      new AndroidInitializationSettings('@mipmap/launcher_icon');
      var initializationSettingsIOS = new IOSInitializationSettings();
      var initializationSettings = new InitializationSettings(
          android: initializationSettingsAndroid, iOS: initializationSettingsIOS);

      flutterLocalNotificationsPlugin.initialize(initializationSettings,
          onSelectNotification: onSelectNotification);
      configureNotifications();

      // For testing purposes print the Firebase Messaging token
      String token = await _firebaseMessaging.getToken();
      print("FirebaseMessaging token: $token");

      _initialized = true;
    
  
  configureNotifications() 
    final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async 
        print("onMessage: $message");
        _showNotification(
            1234,
            "$message['notification']['title']",
            "$message['notification']['body']",
            "$message['data']['order_id']");
        return;
      ,
      onBackgroundMessage: myBackgroundMessageHandler,
      onLaunch: (Map<String, dynamic> message) async 
        print("onLaunch: $message");
        return;
      ,
      onResume: (Map<String, dynamic> message) async 
        print("onResume: $message");
        onSelectNotification("$message['data']['order_id']");
      ,
    );
    _firebaseMessaging.requestNotificationPermissions(
        const IosNotificationSettings(
            sound: true, badge: true, alert: true, provisional: true));
    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) 
      print("Settings registered: $settings");
    );
    _firebaseMessaging.getToken().then((String token) 
      assert(token != null);
    );
  

【问题讨论】:

【参考方案1】:

第一个问题是在main中的初始化

PushNotificationsManager().init();

await Firebase.initializeApp();

并使用此代码打开活动或屏幕。

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) 
      print('A new onMessageOpenedApp event was published!');
      Navigator.pushNamed(context, '/message',
          arguments: MessageArguments(message, true));
    );

谢谢

【讨论】:

感谢您的帮助,但firebase_messaging 的这个版本的7.0.3 没有onMessageOpenedApp 功能,因此我在FirebaseMEssaging.configure() 中使用onLaunch:(Map&lt;String,dynamic&gt; message) 处理它,如办公文档中所述https://pub.dev/packages/firebase_messaging/versions/7.0.3,我也已经有了await Firebase.initializeApp();,只是忘了提,更新问题 使用 void _navigateToItemDetail(Map&lt;String, dynamic&gt; message) final Item item = _itemForMessage(message); Navigator.popUntil(context, (Route&lt;dynamic&gt; route) =&gt; route is PageRoute); if (!item.route.isCurrent) Navigator.push(context, item.route); 并在启动时使用:_navigateToItemDetail(message);

以上是关于单击 FCM 通知时,Flutter Notification 挂起的意图被取消的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 上单击背景通知时如何导航?

Flutter 和 FCM(Firebase 云消息传递)onMessage、onResume 和 onLaunch 在单击通知时未触发(包:firebase_messaging 7.0.0)

后台 FCM 触发时生成 Flutter 本地通知

当应用程序处于后台/终止并收到 FCM 通知时,如何在 Flutter 中显示本地通知?

应用程序终止时 FCM 推送通知 FLUTTER

如何在接收基于 Flutter 构建的 FCM 推送通知时修复应用程序崩溃