You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现通知跳转至关联页面?(App终止/后台状态适配)

通知跳转关联页面问题:前台正常,后台/终止状态失效

我正在实现通知跳转至关联页面的功能,目前App处于前台时跳转正常,但App在终止或后台状态下无法触发跳转逻辑。我在Home页面的initState方法中通过onMessageOpenedApp监听通知并调用API,相关代码如下:

Firebase Messaging 配置代码

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  RemoteNotification? notification = message.notification;
  AndroidNotification? android = message.notification?.android;
  AppleNotification? apple = message.notification?.apple;
  if (notification != null && !kIsWeb) {
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
          ),
          iOS: const IOSNotificationDetails()),
    );
  }
}

Future<void> iniciliazarFlutterLocalNotifications() async {
  final NotificationAppLaunchDetails? notificationAppLaunchDetails = !kIsWeb &&
      Platform.isLinux
      ? null
      : await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();

  var androidSettings =
  const AndroidInitializationSettings('mipmap/launcher_icon');

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  if (!kIsWeb) {
    channel = const AndroidNotificationChannel(
      'high_importance_channel', // id
      'High Importance Notifications', // title/ description
      importance: Importance.high,
      ledColor: Colors.blue);

    var iOSSettings = const IOSInitializationSettings(
      requestSoundPermission: false,
      requestBadgePermission: false,
      requestAlertPermission: false,
    );
    var initSetttings =
        InitializationSettings(android: androidSettings, iOS: iOSSettings);
    flutterLocalNotificationsPlugin.initialize(initSetttings);

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
        AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
        IOSFlutterLocalNotificationsPlugin>()
        ?.requestPermissions(
          alert: true,
          badge: true,
          sound: true,
        );

    await FirebaseMessaging.instance
        .setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification? notification = message.notification;
      AndroidNotification? android = message.notification?.android;
      AppleNotification? apple = message.notification?.apple;
      if (notification != null && !kIsWeb) {
        flutterLocalNotificationsPlugin.show(
          notification.hashCode,
          notification.title,
          notification.body,
          NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
              ),
              iOS: const IOSNotificationDetails()),
        );
      }
    });
  }
}

HomeScreen 通知处理代码

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  void initState() {
    super.initState();
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      if (message.data.containsKey('idReferance')) {
        Provider.of<CustomerProvider>(context, listen: false)
            .getTrackingInformationList(TrackingInformationFilterRequestModel(
                searchBox: message.data['idReferance']));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

问题原因及解决办法

核心问题

onMessageOpenedApp仅在App从后台被通知唤起时生效,当App完全终止时,这个监听不会触发——因为此时Home页面的initState还未执行。另外,后台消息处理逻辑里没有绑定通知点击后的跳转业务。

具体修复步骤

  1. 处理App终止状态下的通知唤起
    在App启动初期(比如main函数或根Widget的initState)调用FirebaseMessaging.instance.getInitialMessage(),它会返回App被终止时点击通知启动的消息,直接在这里处理跳转逻辑:

    // 在根Widget的initState或main函数中添加
    void checkInitialMessage() async {
      RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
      if (initialMessage != null && initialMessage.data.containsKey('idReferance')) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          // 确保Provider已初始化后执行API调用
          Provider.of<CustomerProvider>(context, listen: false)
              .getTrackingInformationList(TrackingInformationFilterRequestModel(
                  searchBox: initialMessage.data['idReferance']));
          // 跳转至目标页面
          Navigator.push(context, MaterialPageRoute(builder: (context) => TargetPage()));
        });
      }
    }
    
  2. 为后台通知添加点击回调
    初始化flutter_local_notifications时设置onSelectNotification回调,同时在显示通知时传入消息数据作为payload:

    // 修改initialize代码,添加点击回调
    await flutterLocalNotificationsPlugin.initialize(
      initSetttings,
      onSelectNotification: (String? payload) async {
        if (payload != null) {
          Map<String, dynamic> data = jsonDecode(payload);
          if (data.containsKey('idReferance')) {
            Provider.of<CustomerProvider>(context, listen: false)
                .getTrackingInformationList(TrackingInformationFilterRequestModel(
                    searchBox: data['idReferance']));
            Navigator.push(context, MaterialPageRoute(builder: (context) => TargetPage()));
          }
        }
      }
    );
    
    // 修改后台/前台消息的show方法,传入payload
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      NotificationDetails(...),
      payload: jsonEncode(message.data) // 将消息data转为JSON字符串
    );
    
  3. 调整监听时机
    将onMessageOpenedApp的监听移到App初始化的早期位置(比如根Widget),避免因Home页面未加载而错过消息。


内容的提问来源于stack exchange,提问作者Burak Aybi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:41:13