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

Flutter中如何仅在App终止时接收FCM通知,后台不接收?

解决方案:仅在App终止状态接收FCM定时通知

要实现只在App终止时接收通知、后台不接收的需求,核心是完全接管FCM通知的展示逻辑,避免系统自动处理后台通知。具体步骤如下:

1. 后端调整:发送数据消息而非通知消息

FCM分为两种消息类型:

  • 通知消息:后台状态下系统会自动弹出通知,无法通过Flutter代码拦截。
  • 数据消息:仅携带自定义数据,系统不会自动展示通知,完全由我们的代码控制展示时机。

要求后端发送FCM时,只包含data字段,不要包含notification字段。示例请求体:

{
  "to": "device_token",
  "data": {
    "title": "定时通知标题",
    "body": "定时通知内容"
  }
}

2. Flutter代码修改

依赖引入

添加本地通知插件,用于手动展示通知:

dependencies:
  flutter_local_notifications: ^16.1.0 # 替换为最新版本

完整代码实现

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

final FlutterLocalNotificationsPlugin _localNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

// 初始化本地通知配置
Future<void> _initLocalNotifications() async {
  const AndroidInitializationSettings androidSettings =
      AndroidInitializationSettings('@mipmap/ic_launcher'); // 替换为你的通知图标
  const InitializationSettings initSettings =
      InitializationSettings(android: androidSettings);
  await _localNotificationsPlugin.initialize(initSettings);
}

// 后台消息回调:后台状态下不做任何通知处理
Future<void> _backgroundMessageHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  // 此处不执行任何通知展示逻辑,直接返回
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化Firebase
  await Firebase.initializeApp(options: const FirebaseOptions(
    apiKey: "apikey",
    appId: "appid",
    messagingSenderId: "senderid",
    projectId: "projid",
  ));

  // 初始化本地通知
  await _initLocalNotifications();

  // 处理App终止状态下的推送:仅在此时展示通知
  RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
  if (initialMessage != null) {
    // 构建本地通知参数
    const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
      'timed_notification_channel', // 渠道ID
      '定时通知', // 渠道名称
      importance: Importance.max,
      priority: Priority.high,
    );
    const NotificationDetails notificationDetails =
        NotificationDetails(android: androidDetails);
    
    // 展示本地通知
    await _localNotificationsPlugin.show(
      DateTime.now().millisecondsSinceEpoch % 10000, // 唯一通知ID
      initialMessage.data['title'] ?? '默认标题',
      initialMessage.data['body'] ?? '默认内容',
      notificationDetails,
    );
  }

  // 注册后台消息回调(后台状态下不处理通知)
  FirebaseMessaging.onBackgroundMessage(_backgroundMessageHandler);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(appBar: AppBar(title: const Text('FCM示例'))),
    );
  }
}

关键逻辑说明

  • getInitialMessage():仅在App从终止状态被推送唤醒时触发,此时我们手动展示本地通知。
  • onBackgroundMessage():App处于后台状态时触发,但此处不执行任何通知展示操作,因此后台不会收到通知。
  • 本地通知插件:用于在终止状态下手动弹出通知,完全替代系统自动展示逻辑。

关于状态区分

可以明确区分App的终止和后台状态:

  • 终止状态:App进程已被杀死,通过getInitialMessage()获取推送。
  • 后台状态:App在后台运行但不可见,通过onBackgroundMessage()接收推送。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:20:20