Flutter应用关闭/闲置时推送通知失效问题及实现方案咨询
Flutter 应用后台/关闭状态接收推送通知解决方案
你的问题核心是没有配置系统级推送通道和后台消息处理逻辑——社交APP之所以能在关闭后收推送,是因为它们依赖了Android的FCM/厂商推送、iOS的APNs这些原生系统服务,而非仅依赖应用自身的运行状态。下面是具体实现步骤和代码:
一、依赖集成(以Firebase Cloud Messaging为例,最通用的方案)
在pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter firebase_core: ^2.15.0 firebase_messaging: ^14.6.5
执行flutter pub get完成依赖安装。
二、Android 端配置
1. 修改AndroidManifest.xml
在android/app/src/main/AndroidManifest.xml中添加权限和推送组件:
<!-- 必要权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <application ...> <!-- FCM消息接收器 --> <receiver android:name="com.google.firebase.messaging.FirebaseMessagingReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <category android:name="${applicationId}" /> </intent-filter> </receiver> <!-- 后台消息处理服务 --> <service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> </application>
2. 创建后台消息服务类
在android/app/src/main/kotlin/[你的包名]/MyFirebaseMessagingService.kt中实现自定义服务,用于在后台/关闭状态下处理推送并显示通知:
package com.yourpackage.name import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage class MyFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { // 应用后台/关闭时收到推送会触发此方法 remoteMessage.notification?.let { showNotification(it.title, it.body) } } private fun showNotification(title: String?, body: String?) { val notificationManager = getSystemService(NOTIFICATION_SERVICE) as android.app.NotificationManager val channelId = "app_push_channel" // Android 8.0+ 必须创建通知渠道 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { val channel = android.app.NotificationChannel( channelId, "应用推送", android.app.NotificationManager.IMPORTANCE_DEFAULT ) notificationManager.createNotificationChannel(channel) } val notification = android.app.NotificationCompat.Builder(this, channelId) .setContentTitle(title) .setContentText(body) .setSmallIcon(R.mipmap.ic_launcher) .setAutoCancel(true) .build() notificationManager.notify(System.currentTimeMillis().toInt(), notification) } }
三、iOS 端配置
1. 开启后台推送模式
在Xcode中打开项目的Info.plist,添加如下配置:
<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array>
2. 配置APNs证书
在Apple Developer后台生成推送证书,将其上传到Firebase控制台,确保FCM与APNs关联(这一步是iOS关闭后收推送的核心)。
四、Flutter 核心代码实现
1. 初始化推送服务
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; // 后台消息处理器(应用关闭时,系统会唤醒应用执行此方法) Future<void> _backgroundMessageHandler(RemoteMessage message) async { await Firebase.initializeApp(); print("后台收到推送: ${message.messageId}"); // 可在此处理数据,比如存储到本地数据库 } void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 注册后台消息处理器 FirebaseMessaging.onBackgroundMessage(_backgroundMessageHandler); // 请求用户推送权限 final settings = await FirebaseMessaging.instance.requestPermission( alert: true, badge: true, sound: true, ); print("用户推送权限状态: ${settings.authorizationStatus}"); // 获取设备推送令牌(用于后端发送推送) final token = await FirebaseMessaging.instance.getToken(); print("FCM令牌: $token"); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Push Demo', home: Scaffold( appBar: AppBar(title: const Text('推送测试')), body: const Center(child: Text('查看通知栏接收推送')), ), ); } }
2. 前台消息处理(可选)
如果需要在应用前台显示通知,可添加如下代码(需先集成flutter_local_notifications库):
// 在StatefulWidget的initState中添加 @override void initState() { super.initState(); FirebaseMessaging.onMessage.listen((RemoteMessage message) { final notification = message.notification; if (notification != null) { // 用flutter_local_notifications显示前台通知 // 示例代码(需先初始化通知插件) // await flutterLocalNotificationsPlugin.show( // 0, // notification.title, // notification.body, // NotificationDetails( // android: AndroidNotificationDetails( // 'app_push_channel', // '应用推送', // importance: Importance.defaultImportance, // ), // ), // ); } }); }
关键注意事项
- 国内Android机型:小米、华为、OPPO等厂商有自己的推送通道,FCM可能被系统后台限制,需额外集成对应厂商的推送SDK才能保证关闭应用后稳定收推送。
- iOS推送格式:发送推送时需确保
apns-push-type为alert(普通通知),如果是数据推送需添加content-available: 1字段。 - 推送消息结构:必须包含
notification字段才能触发系统通知栏显示,纯数据消息需要后台服务自行处理并显示通知。
内容的提问来源于stack exchange,提问作者Cristiano Z
相关产品推荐
相关产品推荐

