0

我正在通过FCMLocalPushNotifications设置推送通知,我能够在应用程序的前台状态和后台进行设置。在应用程序的终止状态下,我确实收到了通知,但是当我按下它时,没有任何动作发生,即使应用程序的前台和后台状态工作正常并将用户导航到通知屏幕,处于终止状态,应用程序只是打开,它不会导航到通知屏幕,只打开应用程序的主屏幕。由于设备未连接,我在控制台日志中看不到错误,但是当我从模拟器启动应用程序时,这就是我开始的结果:

I/flutter ( 3829): Got a message whilst in the terminated state!
I/flutter ( 3829): Message data: null

pushNotifications()这在方法内部调用FirebaseMessaging.instance.getInitialMessage().then()...

这是里面带有注释的代码:

处理推送通知的逻辑:

Future<void> pushNotifications() async {
  await Firebase.initializeApp();
  RemoteMessage initialMessage =
      await FirebaseMessaging.instance.getInitialMessage();

  if (initialMessage != null) {
    _handleMessage(initialMessage);
  }
/// THIS IS NOT WORKING, IT OPENS THE APP BUT DOESN'T NAVIGATE TO THE DESIRED SCREEN
  ///gives you the message on which user taps
  ///and it opened the app from terminated state
  FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage message) {
    LocalNotificationService.display(message);
    print('Got a message whilst in the terminated state!');
    print('Message data: ${message.data}');
    if (message != null) {  
      print('terminated state');
    }
  });

  ///forground work
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    LocalNotificationService.display(message);
    print('Got a message whilst in the foreground!');
    print('Message data: ${message.data}');
  });


///EVEN THOUGH IT IS SUPPOSED TO WORK LIKE THIS, I ONLY MANAGED TO MAKE IT WORK WITH BACKGROUND HANDLER, THIS METHOD NEVER TRIGGERS
  ///When the app is in background but opened and user taps
  ///on the notification
  FirebaseMessaging.onMessageOpenedApp.listen((message) {
    print('Got a message whilst in the background!');
    print('Message data: ${message.data}');
    _handleMessage(message);
    LocalNotificationService.display(message);
  });
}


///THIS HANDLES THE NOTIFICATIONS WHEN THE APP IS IN THE BACKGROUND
Future<void> _handleMessage(RemoteMessage message) async {
  await Firebase.initializeApp();
  if (message.data != null) {
    print('message handler');
    LocalNotificationService.display(message);/// ALL OF THESE CALLED FROM THE LocalNotificationService CLASS BELOW
  }
}
///MAIN METHOD, WHERE I INITIALIZE FIREBASE AND THE METHODES ABOVE(pushNotifications()), HANDLE THE MESSAGES WITH onBackgroundMessage(_handleMessage),
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  pushNotifications();
  var initializationSettingsAndroid =
      AndroidInitializationSettings("@mipmap/ic_launcher");
  var initializationSettingsIOS = IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
      );
  await Firebase.initializeApp();
  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );
  FirebaseMessaging.onBackgroundMessage(_handleMessage);
  runApp(MyApp());
}

我的本地通知服务类:

class LocalNotificationService {
  static final FlutterLocalNotificationsPlugin _notificationsPlugin =
      FlutterLocalNotificationsPlugin();

  static void initialize(BuildContext context) {
    final InitializationSettings initializationSettings =
        InitializationSettings(
            android: AndroidInitializationSettings("@mipmap/ic_launcher"));
    _notificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (String payloadData) async {
     
      if (payloadData!= null) {
        
          Navigator.pushNamed(context, NotificationsScreen.id);
      }
    });
  }

  static void display(RemoteMessage message) async {
    try {
      final id = DateTime.now().millisecondsSinceEpoch ~/ 1000;

      final NotificationDetails notificationDetails = NotificationDetails(
          android: AndroidNotificationDetails(
        "push notifications",
        "push notifications",
        "push notifications",
        importance: Importance.max,
        priority: Priority.high,
      ));

      await _notificationsPlugin.show(
        id,
        'push notifications',
        'You have received a new push notification!',
        notificationDetails,
        payload: message.data['default'], // THIS IS NULL WHEN IN TERMINATED STATE OF APP
      );

    } on Exception catch (e) {
      print('exception: ' + e.toString());
    }
  }
}

所以就像我说的,前台和后台状态都在工作并且对应于正确的屏幕,但终止的应用程序状态根本不对应,但它确实显示通知并在点击它时打开应用程序。

我错过了什么吗?我主要是自己遵循文档和一些东西,但它仍然没有按预期工作。

任何形式的帮助表示赞赏,在此先感谢!

4

2 回答 2

0

我一直无法完全破解您描述的问题,这非常令人沮丧。

到目前为止,这是我想出的,我会把它放在这里,因为它可以帮助你:

有 3 种类型的消息datanotificationmixed

如果您使用纯数据有效负载

  • 该消息基本上是无声的。
  • onMessage应用程序前台时确实响应数据通知
  • onMessageOpenedApp在任何场景下都不会触发数据消息
  • onBackgroundMessage用于在终止状态或使用本地通知的背景状态时显示消息
  • 由您(使用本地通知包)来处理他们的点击,使用onSelectNotification
    await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: selectNotification
    );
  • 你不能onSelectNotification在所有这些场景中使用(据我所知,***这对我来说是一个绊脚石

如果您使用纯通知或混合有效负载

  • 当应用程序处于后台(但不是前台)时,FCM 包将为您显示通知

  • onMessage应用程序前台时确实响应数据

  • onMessageOpenedApp将在后台状态下单击通知时触发(但不是终止状态)

  • onBackgroundMessage将触发,但与上面不同,您不应使用它来显示通知,因为这将强制双重通知(一个由 FCM 包处理,另一个由您手动完成)

  • 点击,在应用程序后台处理时由包处理,但在前台处理时由您处理。*** 可能也终止了,还不确定。

正如我所提到的,我已经列出了一些事实,因为我到目前为止已经弄清楚了。它非常棘手和令人沮丧。让我慢下来的是,当使用混合有效负载(我一直在使用的)时,通知要么根本不来,要么按照自己的节奏来(发送后几个小时)。

如果您在这个问题上取得进展,请告诉我,我认为我们在同一条船上......

于 2022-01-17T18:36:23.927 回答
0

@GrandMagus 幸运的是,我刚刚开始工作!(得到onMessageOpenedApp触发所以我做了一些改变,但我不确定是哪一个让它开始了。

  • 我清除了所有缓存并删除了该应用程序并从头开始安装。
  • 编辑 AndroidManifest.xml 以按照文档的建议进行更改,以防您这样做: <intent-filter> <action android:name="FLUTTER_NOTIFICATION_CLICK" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>

<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="high_importance_channel" />

  • 将我的有效载荷更改为混合datanotification. 我包含FLUTTER_NOTIFICATION_CLICK在我的有效载荷中。我可以进一步解释一下,以防你不知道那是什么。它的关键是让你的payload至少拥有这些notification信息。这会强制包创建通知,然后响应点击。在这种情况下不要自己处理创建本地推送通知,否则您将收到 2 个通知。如果你得到两个,你会注意到包生成的那个实际上会运行onMessageOpenedApp
  • 我开始在Release mode. 我想知道允许抬头通知的 AndroidManifest.xml 更改是否仅在将它们放置在每个 .xml 文件中时才有效。在这种情况下,我正在编辑release文件,但在调试版本上进行测试
于 2022-01-18T21:57:46.643 回答