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

无付费Firebase账户时,Flutter聊天应用后台/关闭状态消息通知实现咨询

Flutter Firebase聊天应用后台/离线通知实现方案(无需Cloud Functions)

优先方案:FCM设备到设备推送(免费且可靠)

不用Cloud Functions也能实现跨设备实时通知,通过FCM的设备到设备推送,由发送消息的客户端直接向接收方的设备令牌推送系统通知,不受应用前台/后台/关闭状态限制。

步骤1:获取并存储设备令牌

初始化Firebase Messaging,获取当前用户的设备令牌,并存入Firebase数据库(比如用户文档):

final fcmToken = await FirebaseMessaging.instance.getToken();
// 将令牌更新到用户文档中
await FirebaseFirestore.instance.collection('users').doc(currentUserId).update({
  'fcmTokens': FieldValue.arrayUnion([fcmToken])
});

步骤2:发送消息时触发FCM推送

用户发送新消息时,从数据库中获取接收方的设备令牌,调用FCM API直接推送通知:

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<void> sendNotification(String receiverToken, String messageContent) async {
  const fcmUrl = 'https://fcm.googleapis.com/fcm/send';
  final headers = {
    'Content-Type': 'application/json',
    'Authorization': 'key=YOUR_FCM_SERVER_KEY', // 从Firebase控制台获取
  };
  final requestBody = jsonEncode({
    'to': receiverToken,
    'notification': {
      'title': '新消息',
      'body': messageContent,
      'sound': 'default'
    },
    'data': {
      'chatId': '目标聊天ID', // 可选,用于点击通知跳转对应聊天
    }
  });

  await http.post(Uri.parse(fcmUrl), headers: headers, body: requestBody);
}

注:YOUR_FCM_SERVER_KEY可从Firebase控制台「项目设置」→「云消息传递」中获取,免费账户完全支持使用。

步骤3:平台配置

  • Android:确保android/app/src/main/AndroidManifest.xml已包含FCM相关配置(FlutterFire初始化时通常自动添加),并申请POST_NOTIFICATIONS权限。
  • iOS:在ios/Runner/Info.plist中添加推送权限配置,同时在Xcode中开启「推送通知」和「后台模式-远程通知」选项。

备选方案:客户端后台数据监听(适配平台限制)

如果必须通过监听Firebase数据变化触发通知,需针对Android和iOS的后台限制分别适配:

Android 实现

  1. 开启数据持久化:保证离线状态下数据同步能力
    // Realtime Database
    FirebaseDatabase.instance.setPersistenceEnabled(true);
    // Firestore
    FirebaseFirestore.instance.enablePersistence();
    
  2. 创建前台服务维持监听:Android后台限制严格,普通后台任务易被回收,需用前台服务保持监听存活:
    import 'package:flutter_background_service/flutter_background_service.dart';
    
    void initBackgroundService() async {
      final service = FlutterBackgroundService();
      await service.configure(
        androidConfiguration: AndroidConfiguration(
          onStart: backgroundServiceCallback,
          autoStart: true,
          isForegroundMode: true, // 开启前台模式,避免被系统杀死
        ),
        iosConfiguration: IosConfiguration(
          autoStart: true,
          onForeground: backgroundServiceCallback,
        ),
      );
    }
    
    @pragma('vm:entry-point')
    void backgroundServiceCallback(ServiceInstance service) async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
    
      // 监听未读新消息
      FirebaseFirestore.instance.collection('messages')
          .where('receiverId', isEqualTo: currentUserId)
          .where('isRead', isEqualTo: false)
          .snapshots()
          .listen((snapshot) {
        for (var docChange in snapshot.docChanges) {
          if (docChange.type == DocumentChangeType.added) {
            // 调用本地通知插件发送通知
            showLocalNotification(docChange.data()['content']);
          }
        }
      });
    }
    
    需在AndroidManifest.xml中添加权限:
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    

iOS 实现

iOS后台限制更严格,只能通过定期后台刷新实现近似实时的消息检测:

  1. 开启后台模式:在ios/Runner/Info.plist中添加:
    <key>UIBackgroundModes</key>
    <array>
      <string>fetch</string>
      <string>remote-notification</string>
    </array>
    
  2. 定期触发数据检查:使用background_fetch插件每隔15分钟(iOS允许的最小间隔)检查一次未读消息:
    import 'package:background_fetch/background_fetch.dart';
    
    void initBackgroundFetch() async {
      BackgroundFetch.configure(
        BackgroundFetchConfig(
          minimumFetchInterval: 15,
        ),
        (String taskId) async {
          // 查询未读消息
          final unreadMessages = await FirebaseFirestore.instance
              .collection('messages')
              .where('receiverId', isEqualTo: currentUserId)
              .where('isRead', isEqualTo: false)
              .get();
          if (unreadMessages.docs.isNotEmpty) {
            showLocalNotification('您有${unreadMessages.docs.length}条未读消息');
          }
          BackgroundFetch.finish(taskId);
        },
      );
    }
    
    注:iOS后台刷新的执行时机由系统控制,无法保证实时性。

总结

优先选择FCM设备到设备推送,免费、实时且跨平台可靠;客户端后台监听仅作为备选方案,受限于平台后台限制,实时性和稳定性较差。

内容的提问来源于stack exchange,提问作者Yash Sahu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:45:41