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

Flutter安卓应用onBackgroundMessage无法触发,求解决方案

解决Firebase后台通知接收失败问题

针对你遇到的前台能收到Firebase通知、后台无法接收的问题,以下是具体排查和修复方案:

1. 修复后台回调的隔离性问题

Firebase的onBackgroundMessage回调运行在单独的Isolate环境中,不能依赖类实例或全局变量,必须是顶级函数且内部完成所有必要初始化。你的代码中直接调用notificationService.showNotification会失败,因为后台环境无法访问这个类实例。

修改_onBackgroundMessage为独立初始化通知:

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:souhi/firebase_options.dart';

// 必须是顶级函数,不能放在类内部
Future<void> _onBackgroundMessage(RemoteMessage message) async {
  // 后台环境必须重新初始化Firebase
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  // 初始化本地通知插件
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  const AndroidInitializationSettings androidInitSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
  final InitializationSettings initSettings = InitializationSettings(android: androidInitSettings);
  await flutterLocalNotificationsPlugin.initialize(initSettings);

  // 创建通知渠道(Android 8.0+必填)
  const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'background_notification_channel',
    '后台通知渠道',
    description: '用于接收后台推送通知',
    importance: Importance.max,
    priority: Priority.high,
  );
  await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(channel);

  // 显示通知
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'background_notification_channel',
    '后台通知渠道',
    importance: Importance.max,
    priority: Priority.high,
  );
  const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);
  
  await flutterLocalNotificationsPlugin.show(
    message.messageId.hashCode,
    message.notification?.title ?? '新通知',
    message.notification?.body ?? '',
    notificationDetails,
  );
}

2. 确保通知渠道配置正确

Android 8.0及以上版本必须配置通知渠道,否则后台通知无法显示。在你的NotificationService中添加渠道创建逻辑,确保前台和后台使用同一渠道ID:

class NotificationService {
  final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

  Future<void> initialize() async {
    // 初始化前台通知
    const AndroidInitializationSettings androidInitSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
    final InitializationSettings initSettings = InitializationSettings(android: androidInitSettings);
    await _flutterLocalNotificationsPlugin.initialize(initSettings);

    // 创建统一的通知渠道
    await _createNotificationChannel();
  }

  Future<void> _createNotificationChannel() async {
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'background_notification_channel', // 和后台回调用的渠道ID一致
      '后台通知渠道',
      description: '用于接收所有推送通知',
      importance: Importance.max,
      priority: Priority.high,
    );
    await _flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(channel);
  }

  // 前台显示通知的方法
  Future<void> showNotification(RemoteMessage message) async {
    const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
      'background_notification_channel',
      '后台通知渠道',
      importance: Importance.max,
      priority: Priority.high,
    );
    const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);
    
    await _flutterLocalNotificationsPlugin.show(
      message.messageId.hashCode,
      message.notification?.title,
      message.notification?.body,
      notificationDetails,
    );
  }
}

3. 检查Firebase消息Payload格式

  • 如果发送的是通知消息(包含notification字段),Firebase会自动在后台显示通知,但需要确保渠道ID匹配。
  • 如果发送的是数据消息(只有data字段),必须在onBackgroundMessage中手动处理并显示通知,Firebase不会自动弹出。

4. 处理厂商后台限制

国内Android厂商(小米、华为、OPPO等)默认会限制应用后台运行,需要手动开启权限:

  • 进入手机「设置」→「应用管理」→ 找到你的应用 → 开启「后台运行权限」「自启动权限」
  • 部分机型需要开启「弹出通知权限」

5. 修正Firebase初始化逻辑

确保Firebase.initializeApp只执行一次,且在注册回调之前完成:

class FirebaseMessagingService {
  final NotificationService _notificationService;

  FirebaseMessagingService(this._notificationService);

  Future<void> initialize() async {
    print('firebase_messaging initialize');

    // 先初始化Firebase
    await Firebase.initializeApp(
      name: 'Monitorer',
      options: DefaultFirebaseOptions.currentPlatform,
    );

    // 设置前台通知展示选项
    await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
      badge: true,
      sound: true,
      alert: true,
    );

    // 注册后台和前台回调
    FirebaseMessaging.onBackgroundMessage(_onBackgroundMessage);
    _registerForegroundMessageListener();
  }

  void _registerForegroundMessageListener() {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
      print('firebase_messaging onMessage listen');
      await _notificationService.showNotification(message);
    });
  }
}

内容的提问来源于stack exchange,提问作者César Espíndola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:33:29