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

Flutter Firebase Messaging实现点击推送跳转指定页面

Flutter Firebase Messaging 实现全场景通知路由跳转

要覆盖前台接收、后台点击、冷启动三种场景的通知路由跳转,核心是解决消息跨组件传递和Context获取的问题,以下是具体实现方案:

1. 全局消息传递工具

定义一个全局的ValueNotifier来跨组件传递通知消息,让主页能实时监听消息变化:

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';

// 全局通知消息通知器
final ValueNotifier<RemoteMessage?> notificationMessage = ValueNotifier(null);

2. 改造顶层消息监听

在main函数中,修改onMessage并添加onMessageOpenedApp监听,将消息同步到全局通知器:

void main() async {
  WidgetsFlutterBinding();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  // 前台接收消息时,同步到全局通知器
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print('Got a message whilst in the foreground!');
    print('Message data: ${message.data}');

    if (message.notification != null) {
      print('Message also contained a notification: ${message.notification}');
    }
    // 传递消息到全局通知器
    notificationMessage.value = message;
  });

  // 后台点击通知时,同步到全局通知器
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print('Message opened from background!');
    notificationMessage.value = message;
  });

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  runApp(const MyApp());
}

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  print("Handling a background message: ${message.messageId}");
}

3. 主页监听消息并实现跳转

在主页的initState中,同时处理冷启动消息和全局通知器的消息变化,调用Navigator完成路由跳转:

import 'package:flutter/material.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
    // 处理冷启动(APP完全关闭)的消息
    _handleInitialMessage();
    // 监听全局通知器的消息变化
    _listenToNotificationMessages();
  }

  void _handleInitialMessage() async {
    RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
    if (initialMessage != null) {
      _navigateToRoute(initialMessage);
    }
  }

  void _listenToNotificationMessages() {
    notificationMessage.addListener(() {
      if (notificationMessage.value != null && mounted) {
        _navigateToRoute(notificationMessage.value!);
        // 处理后重置消息,避免重复跳转
        notificationMessage.value = null;
      }
    });
  }

  void _navigateToRoute(RemoteMessage message) {
    // 从消息data中取出预设的路由字段(比如你推送时携带的"route"参数)
    String? targetRoute = message.data['route'];
    if (targetRoute != null) {
      Navigator.pushNamed(context, targetRoute);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: const Center(child: Text('Home Page')),
    );
  }
}

4. 补充:后台静默接收消息的处理

如果需要处理APP后台运行时接收消息但未点击通知的场景(比如自动跳转),可以用SharedPreferences存储待处理消息,待APP回到前台时检查并跳转:

第一步:修改后台消息处理函数

import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  print("Handling a background message: ${message.messageId}");
  // 将消息数据存入SharedPreferences
  SharedPreferences prefs = await SharedPreferences.getInstance();
  await prefs.setString('pending_notification', jsonEncode(message.data));
}

第二步:在主页添加待处理消息检查

@override
void initState() {
  super.initState();
  _handleInitialMessage();
  _listenToNotificationMessages();
  // 检查后台静默接收的待处理消息
  _checkPendingNotification();
}

void _checkPendingNotification() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String? pendingData = prefs.getString('pending_notification');
  if (pendingData != null && mounted) {
    Map<String, dynamic> messageData = jsonDecode(pendingData);
    String? targetRoute = messageData['route'];
    if (targetRoute != null) {
      Navigator.pushNamed(context, targetRoute);
      // 清除已处理的消息
      await prefs.remove('pending_notification');
    }
  }
}

内容的提问来源于stack exchange,提问作者Ruder Buster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:55:33