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一样,这里不细写了

收到消息--测试成功

相关推荐
A懿轩A5 小时前
【2025版 OpenHarmony】GitCode 口袋工具 v1.0.3:Flutter + HarmonyOS 深色模式全面启用
flutter·harmonyos·openharmony·gitcode·开源鸿蒙
食品一少年5 小时前
【Day7-10】开源鸿蒙Flutter 常用组件封装实战(2)
flutter·华为·harmonyos
CareyWYR8 小时前
安康记1.1.x版本发布
ios·app
岁月向前9 小时前
SwiftUI和UIKit区别
ios
修炼者9 小时前
Android Studio的技巧
android·android studio
非专业程序员10 小时前
iOS 实现微信读书的仿真翻页
ios·swiftui·swift
非专业程序员Ping11 小时前
iOS 实现微信读书的仿真翻页
ios·swiftui·swift
谢斯13 小时前
编译AppFlowy
flutter
灰灰勇闯IT15 小时前
Flutter×鸿蒙深度融合指南:从跨端适配到分布式能力落地(2025最新实战)
分布式·flutter·harmonyos
x.Jessica16 小时前
关于Flutter在Windows上开发的基本配置时遇到的问题及解决方法
windows·flutter