Flutter集成FCM离线推送---完整步骤

flutter中使用消息推送的方式有很多,若要实现离线推送等功能,需要集成第三方的推送,flutter官方推荐使用Firebase Cloud Messaging (FCM) 。

  • 如果App针对的是国内用户的话,不用考虑这个,FCM推送的必要条件是:有VPN,且安卓手机拥有谷歌三大件

前置

  • 需要先完成firebase配置,这一步请参考Flutter集成apple、google登陆,其中的:1. firebase项目创建、2. firebase配置章节
  • 需要拥有firebase账号,科学上网,一部有google三大件且能翻墙的安卓手机或模拟器,android studio模拟器如何上网请参考:Android虚拟机如何联网
  • 如果是iOS设备,必需使用真机进行调试,模拟器是无法收到消息的

Android接入FCM

下载依赖

pubspec.yaml

yml 复制代码
dependencies:
	# FCM推送
  firebase_messaging: ^14.7.2
  flutter_local_notifications: ^16.1.0

封装代码

lib/firebase/fcm/fcm_utils.dart

  • 具体代码可以通过调试,加深理解
  • 具体意思可以看看注释
dart 复制代码
import 'dart:convert';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
// 这两个是封装的路由,可不用
import 'package:planx_app/router/navigator_util.dart';
import 'package:planx_app/router/routes.dart';

class FirebaseApi {
  final _firebaseMessaging = FirebaseMessaging.instance;
  final _localNotifications = FlutterLocalNotificationsPlugin();
  final _androidChannel = const AndroidNotificationChannel(
    'planx', 'PlanX Android',  // 这些信息根据自己的app定义
    description: "PlanX Android description",
    importance: Importance.defaultImportance);

  // 本地消息,处理android的前台消息
  Future initLocalNotifications() async {
    const iOS = DarwinInitializationSettings();
    // @drawable/ic_launcher是应用的图标,路径是:android/app/src/main/res/drawable/ic_launcher.png
    const android = AndroidInitializationSettings('@drawable/ic_launcher');
    const settings = InitializationSettings(android: android, iOS: iOS);
    await _localNotifications.initialize(settings,
     onDidReceiveNotificationResponse: (NotificationResponse response) {
       // android 前台消息点击
       final message = RemoteMessage.fromMap(jsonDecode(response.payload!));
       print(response);
       // 处理收到消息
       handleMessage(message);
     });
    final platform = _localNotifications.resolvePlatformSpecificImplementation<
      AndroidFlutterLocalNotificationsPlugin>();
    await platform?.createNotificationChannel(_androidChannel);
  }

  // 初始化,获取设备token
  Future<void> initNotifications() async {
    await _firebaseMessaging.requestPermission();
    final fCMToken = await _firebaseMessaging.getToken();
    print(fCMToken); // 这个就是设备token,后端通过这token给设备发送信息
    initPushNotifications();
    initLocalNotifications();
  }

  // 初始化接收消息的各种回调
  Future initPushNotifications() async {
    await _firebaseMessaging.setForegroundNotificationPresentationOptions(
      alert: true, badge: true, sound: true);

    // 打开app时,会执行该回调,获取消息(通常是程序终止时,点击消息打开app的回调)
    _firebaseMessaging.getInitialMessage().then(
      (RemoteMessage? message) {
        if (message == null) return; // 没有消息不执行后操作
        handleMessage(message);
      },
    );

    // 后台程序运行时,点击消息触发
    FirebaseMessaging.onMessageOpenedApp
      .listen((RemoteMessage message) => handleMessage(message));

    // 前台消息,android不会通知,所以需要自定义本地通知(iOS没有前台消息,iOS的前台消息和后台运行时一样的效果)
    FirebaseMessaging.onMessage.listen((message) {
      final notification = message.notification;
      if (notification == null) return;
      if (Platform.isIOS) return;
      _localNotifications.show(
        notification.hashCode,
        notification.title,
        notification.body,
        NotificationDetails(
          android: AndroidNotificationDetails(
            _androidChannel.id,
            _androidChannel.name,
            channelDescription: _androidChannel.description,
            icon: '@drawable/ic_launcher',
          )),
        payload: jsonEncode(message.toMap()));
    });

    // 后台处理,后台程序运行时收到消息,不打开app也会执行的回调
    // FirebaseMessaging.onBackgroundMessage(FirebaseApi.handleBackgroundMessage);
  }

  // 处理收到的消息,比如跳转页面之类(这里需要无context跳转,可以参考我写的flutter路由配置篇章介绍)
  void handleMessage(RemoteMessage message) {
    NavigatorUtil.push(Routes.indexPage);
  }

  // static Future<void> handleBackgroundMessage(RemoteMessage message) async {
  //   print('后台消息');
  //   // BotToast.showText(text: '后台消息:${message.toString()}');
  //   print('title:${message.notification?.title}');
  //   print('body:${message.notification?.body}');
  //   print('payload:${message.data}');
  //   print('message:${message}');
  // }
}

在main中初始化

  • 初始化写在firebase配置后面

lib/main.dart

dart 复制代码
// ...
await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform);

FcmUtils().initNotifications(); // 初始化,获取token
// ...

运行与测试项目:

  • 点击允许,获取到token

打开firebase console测试

  • 选择发送测试消息
  • 将刚刚获取到的token,粘贴到输入框--->添加设备-->点击测试
  • 成功收到消息,后面再测试:终止程序是否收到消息,或后台运行是否收到消息

iOS接入FCM

配置项目

  • 打开firebase-->项目-->iOS应用
  • 下载这个文件,替换项目中的文件:ios/Runner/GoogleService-Info.plist
  • 点击查看SDK说明-->第四步
  • 根据提示复制到项目中

ios/Runner/AppDelegate.swift

配置证书

生成证书

  • 打开钥匙串,创建证书

输入自己的邮箱--->点击继续

  • 打开开发者后台,创建证书
  • 选择服务
  • 下载证书
  • 双击下载下来的证书
  • 打开钥匙串-->鼠标右键-->导出
  • 设置密码 --> 输入登陆密码--->导出成功,文件是.p12的文件

上传证书到firebase

xcode添加能力

运行和测试项目

  • 代码与android一致,这里就不贴了
  • 需要真机运行,模拟器无法收到消息

此时可能有报错,主要是网络原因

解决方案:

  • 终端开启代理(自行查一下搜索引擎)
  • cd ./ios
  • pod install

再次运行

  • 如果没有获取到token,请检查一下手机是否联网,并且科学上网
  • 获取token,放到firebase中测试,方式与Android一样,这里不细写了

收到消息--测试成功

相关推荐
yuanlaile1 小时前
2026年全新Flutter 跨平台开发全栈学习资料整理
flutter·getx·鸿蒙 next·flutter开发鸿蒙·flutter入门实战·flutter全栈
浪潮IT馆3 小时前
Android Studio 非最新版本下载安装教程
android·ide·android studio
Anhty6 小时前
2026最新免费手机音频处理工具 !!
android·功能测试·ios·智能手机·音视频
2501_915909068 小时前
iOS应用从开发到上架App Store的完整发布流程与步骤指南
android·ios·小程序·https·uni-app·webview
初雪云9 小时前
UniApp 云打包拿到 IPA 后,真正的发布工作才刚开始
ios·自动化·编辑器·产品经理·iphone
Lancker11 小时前
没有 Mac 也能上架 iOS:GitHub Actions 全自动构建 + 签名 + TestFlight 送审实录
macos·ios·github
茶底世界之下11 小时前
晚霞要多暖?用 Awaking 只改色温做一次取舍
ios
恋猫de小郭12 小时前
Genkit Dart 1.0 发布,Flutter 原生的 AI Agent 终于完整了
android·前端·flutter
第10086个小白12 小时前
flutter桌面端打包方式(Inno Setup Compiler)版本
前端·flutter
酒神dnspup13 小时前
多地区网站可用性监控怎么做?DNSPup 从基线到告警的完整实战
运维·ios·云计算·iphone·dns·网络监控