Flutter点击FCM通知打开APP后未弹窗的问题排查
问题原因
当APP处于完全关闭(终止)状态时,点击FCM通知启动APP,消息不会触发前台场景的onMessage回调,而是需要通过FirebaseMessaging.instance.getInitialMessage()获取启动时的消息。你当前的代码仅处理了前台接收消息的逻辑,缺失冷启动场景的消息处理,导致弹窗不出现。
修复步骤
1. 在main.dart中处理冷启动消息
初始化Firebase后,检查是否是通过点击FCM通知启动的APP,若存在启动消息,将其传递给后续页面:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 获取冷启动时的FCM消息 RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); runApp(MyApp(initialNotification: initialMessage)); } class MyApp extends StatelessWidget { final RemoteMessage? initialNotification; const MyApp({super.key, this.initialNotification}); @override Widget build(BuildContext context) { return MaterialApp( home: LoadingScreen(initialNotification: initialNotification), ); } }
2. 在LoadingScreen中传递消息到HomeScreen
由于页面流程是main→loading→home,需在LoadingScreen完成加载逻辑后,将启动消息传递给HomeScreen:
class LoadingScreen extends StatefulWidget { final RemoteMessage? initialNotification; const LoadingScreen({super.key, this.initialNotification}); @override State<LoadingScreen> createState() => _LoadingScreenState(); } class _LoadingScreenState extends State<LoadingScreen> { @override void initState() { super.initState(); // 模拟加载流程(如登录校验) Future.delayed(const Duration(seconds: 2), () { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => HomeScreen(initialNotification: widget.initialNotification), ), ); }); } @override Widget build(BuildContext context) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } }
3. 在HomeScreen中统一处理所有场景的消息
修改HomeScreen,同时处理冷启动消息、前台消息、后台点击通知的消息:
class HomeScreen extends StatefulWidget { final RemoteMessage? initialNotification; const HomeScreen({super.key, this.initialNotification}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override void initState() { super.initState(); // 处理冷启动带来的消息 if (widget.initialNotification != null) { _showNotificationDialog(widget.initialNotification!); } // 处理前台实时接收的消息 FirebaseMessaging.onMessage.listen((RemoteMessage message) { _showNotificationDialog(message); }); // 处理APP在后台时点击通知的情况 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { _showNotificationDialog(message); }); } void _showNotificationDialog(RemoteMessage message) { // 弹窗展示逻辑,示例使用AlertDialog showDialog( context: context, builder: (context) => AlertDialog( title: Text(message.notification?.title ?? '通知'), content: Text(message.notification?.body ?? ''), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } @override Widget build(BuildContext context) { return const Scaffold( body: Center(child: Text('首页')), ); } }
4. 检查FCM通知Payload配置
确保发送的FCM通知包含click_action: FLUTTER_NOTIFICATION_CLICK(Android端必填),否则点击通知可能无法正确触发回调,示例Payload:
{ "notification": { "title": "测试通知", "body": "这是一条测试消息", "click_action": "FLUTTER_NOTIFICATION_CLICK" }, "data": { "key": "value" }, "to": "目标设备Token" }
内容的提问来源于stack exchange,提问作者H Amr
相关产品推荐
相关产品推荐

