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

Flutter点击Firebase推送(前后台/终止态)无法跳转指定页面问题

问题根因

你遇到的两类点击失效问题,本质是配置冲突+逻辑时序错配,和你使用的firebase_messaging: ^11.2.6版本的默认行为强相关:

  • 手动在AndroidManifest.xml中添加FLUTTER_NOTIFICATION_CLICK的intent-filter是旧版(<10.0.0)firebase_messaging的适配逻辑,11.x版本已经在库自身的清单文件中自动注册了正确的点击分发路由,手动加自定义filter会抢占事件通道,直接导致onMessageOpenedApp永远无法触发
  • 前台状态下通过flutter_local_notifications展示通知时,没有配置正确的点击透传参数,点击事件根本没有回传到Firebase Messaging的监听链路
  • 终止态下getInitialMessage调用时机、跳转执行时机不对:如果等SplashScreen自动跳转到首页之后才获取初始消息,或者导航栈还没完成初始化就执行跳转,自然会停留在首页

分步修复方案

第一步:修正Android端清单配置

直接删掉你之前手动添加的FLUTTER_NOTIFICATION_CLICK相关intent-filter,保留MainActivity的默认配置即可:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:windowSoftInputMode="adjustResize">
    <!-- 仅保留默认的启动页intent-filter,删掉所有自定义的FLUTTER_NOTIFICATION_CLICK相关filter -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

同时把推送服务端载荷里的"click_action": "FLUTTER_NOTIFICATION_CLICK"字段删掉,11.x版本不需要在推送载荷中传这个参数,传了反而会触发自定义intent路由,绕过Firebase的事件监听逻辑。

第二步:修正通知点击事件透传逻辑

本地通知初始化配置

初始化FlutterLocalNotificationsPlugin时不要在点击回调里写跳转逻辑,避免和Firebase的事件分发冲突:

const AndroidInitializationSettings androidInitSetting = AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initSetting = InitializationSettings(android: androidInitSetting);
await flutterLocalNotificationsPlugin.initialize(initSetting);

前台消息展示配置

前台收到消息触发onMessage监听、手动弹本地通知时,才需要给Android渠道配置加clickAction参数,保证点击事件能回传给Firebase:

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
  final RemoteNotification? notification = message.notification;
  final AndroidNotification? androidConfig = message.notification?.android;
  if (notification != null && androidConfig != null) {
    flutterLocalNotificationsPlugin.show(
      notification.hashCode,
      notification.title,
      notification.body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          'high_importance_channel',
          '高优先级通知',
          importance: Importance.max,
          priority: Priority.high,
          // 仅在这里加clickAction,不要在推送载荷里加
          clickAction: 'FLUTTER_NOTIFICATION_CLICK',
        ),
      ),
    );
  }
});

改完这部分,后台状态下Firebase自动弹出的通知、前台状态下你手动弹的本地通知,点击后都会正常触发onMessageOpenedApp监听。

第三步:修正终止态跳转时序

getInitialMessage必须在应用启动的第一时间调用,不能等SplashScreen的定时跳转逻辑执行完再调用,跳转逻辑要等导航栈挂载完成后再执行:

  1. 在main函数中初始化Firebase后立刻获取终止态点击的消息,存为全局变量:
RemoteMessage? initialMessage;
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  // 启动第一时间获取终止态通知点击的消息
  initialMessage = await FirebaseMessaging.instance.getInitialMessage();
  // 注册后台消息处理器
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(const MyApp());
}
  1. 在根路由(或MaterialApp的home组件)的初始化逻辑中,等第一帧渲染完成、导航栈可用后再执行跳转:
@override
void initState() {
  super.initState();
  // 监听前后台运行状态下的通知点击事件
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    _navigateToTargetPage(message.data);
  });

  // 等页面渲染完成后处理终止态跳转
  WidgetsBinding.instance.addPostFrameCallback((_) {
    if (initialMessage != null) {
      _navigateToTargetPage(initialMessage!.data);
    }
  });
}

// 统一封装跳转逻辑,根据消息里的自定义参数跳转指定页
void _navigateToTargetPage(Map<String, dynamic> msgData) {
  if(msgData['page'] == 'detail') {
    Navigator.push(context, MaterialPageRoute(
      builder: (context) => DetailPage(contentId: msgData['id'])
    ));
  }
  // 其他页面路由逻辑按需补充
}

第四步:版本校验

你通过dependency_overrides锁定firebase_messaging_platform_interface: 3.1.6的配置是兼容的,改完代码后执行flutter clean再重新编译,执行flutter pub deps确认依赖树中firebase_messaging_platform_interface版本确实为3.1.6,没有被其他依赖覆盖即可。


验证注意事项

测试时不要用Flutter的热重载/热重启功能,每次修改配置后要完全停止应用重新启动——Firebase的消息监听在热重载后不会重新注册,会出现事件不触发的假象。验证顺序:

  1. 完全杀掉应用,发送推送,点击通知确认能直接打开应用跳转至目标页
  2. 应用在前台停留时收到推送,点击通知确认触发监听、正常跳转
  3. 应用切到后台停留时收到推送,点击通知确认触发监听、正常跳转

内容的提问来源于stack exchange,提问作者Ahmed Elsayed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 03:24:28