1. 简介

本教程将演示如何在Spring Boot应用中集成Google的Firebase Cloud Messaging(FCM)服务,向Web和移动应用推送通知。

2. 什么是FCM?

Firebase Cloud Messaging(简称FCM)是一个基于云的消息服务,提供以下核心功能:

  • 可靠地向移动端或Web端(统称为"客户端")发送消息
  • 通过主题或订阅机制,实现消息的全量广播或定向投递
  • 在服务端接收来自客户端的消息

实际应用场景包括:

  • 向特定用户推送专属优惠信息
  • 通知所有用户新功能上线
  • 即时通讯/聊天应用
  • 向特定客户发送定向通知

3. 应用架构

典型的FCM应用架构包含服务端、客户端和FCM平台三部分:

架构图

本教程重点讲解服务端实现。我们将构建一个基于Spring Boot的服务,通过REST接口探索多种通知推送方式:

  • 向主题发布通知
  • 向特定客户端推送通知
  • 向多个主题组合推送通知

核心概念包括客户端、主题和订阅。

3.1. 主题

主题是具有共同属性的通知中心。例如:

  • 金融应用可为不同交易资产创建主题
  • 体育应用可为每支球队或赛事创建主题

3.2. 客户端

客户端是安装在移动设备或浏览器中的应用实例。接收通知的步骤:

  1. 使用SDK向Firebase项目注册
  2. 获取唯一注册令牌(registration token)
  3. 将令牌发送至服务端用于定向推送

3.3. 订阅

订阅表示客户端与主题的关联关系。服务端通过API调用创建订阅,需提供:

  • 一个或多个客户端注册令牌
  • 主题名称

4. Firebase项目设置

Firebase项目作为云资源的容器,提供免费初始配额。使用FCM需先创建项目:

  1. 访问Firebase控制台
  2. 登录后进入主页:

控制台首页

  1. 点击"添加项目"开始向导:
    • 首先命名项目:

项目命名

⚠️ 注意:项目名称不唯一,但项目ID唯一,容易混淆

  • 禁用Google Analytics(本教程不需要):

Analytics设置

  1. 完成创建后进入项目管理页面

5. 生成服务账号

服务端调用Firebase API需要服务账号凭证。获取步骤:

  1. 进入项目设置页
  2. 选择"服务账号"标签页:

服务账号设置

  1. 点击"生成新私钥"下载JSON凭证文件 ✅ 生产环境应创建最小权限专用账号(需IAM知识) ❌ 本教程直接使用默认管理员账号

⚠️ 务必妥善保管私钥文件!

6. Maven依赖

在Spring Boot项目中添加firebase-admin依赖:

<dependency>
    <groupId>com.google.firebase</groupId>
    <artifactId>firebase-admin</artifactId>
    <version>9.1.1</version>
</dependency>

最新版本见Maven Central

7. Firebase消息配置

FirebaseMessaging是发送消息的核心入口。由于线程安全,我们通过@Bean创建单例:

@Bean
FirebaseMessaging firebaseMessaging(FirebaseApp firebaseApp) {
    return FirebaseMessaging.getInstance(firebaseApp);
}

需先配置FirebaseApp

@Bean
FirebaseApp firebaseApp(GoogleCredentials credentials) {
    FirebaseOptions options = FirebaseOptions.builder()
      .setCredentials(credentials)
      .build();

    return FirebaseApp.initializeApp(options);
}

FirebaseOptions支持自定义:

  • 超时设置
  • HTTP请求工厂
  • 服务端点
  • 线程工厂

最后配置凭证:

@Bean
GoogleCredentials googleCredentials() {
    if (firebaseProperties.getServiceAccount() != null) {
        try (InputStream is = firebaseProperties.getServiceAccount().getInputStream()) {
            return GoogleCredentials.fromStream(is);
        }
    } 
    else {
        // 使用默认凭证链(适用于GKE环境)
        return GoogleCredentials.getApplicationDefault();
    }
}

此方案便于本地测试多账号环境,避免频繁修改GOOGLE_APPLICATION_CREDENTIALS环境变量。

8. 向主题发送消息

发送步骤:

  1. 构建Message对象(使用Builder模式):

    Message msg = Message.builder()
    .setTopic(topic)
    .putData("body", "some data")
    .build();
    
  2. 调用send()发送:

    String id = fcm.send(msg);
    

返回的id是FCM生成的消息标识,可用于追踪。异步版本sendAsync()返回ApiFuture,兼容响应式框架(如Project Reactor)。

9. 向特定客户端发送消息

使用客户端注册令牌替代主题名:

Message msg = Message.builder()
  .setToken(registrationToken)
  .putData("body", "some data")
  .build();

批量发送(最多500个客户端):

MulticastMessage msg = MulticastMessage.builder()
  .addAllTokens(message.getRegistrationTokens())
  .putData("body", "some data")
  .build();

BatchResponse response = fcm.sendMulticast(msg);

BatchResponse包含消息ID和各客户端的发送错误信息。

10. 向多主题组合发送消息

通过条件表达式定义目标受众。例如:

('T1' in topics || 'T2' in topics) && !('T3' in topics)

构建消息:

Message msg = Message.builder()
  .setCondition("('T1' in topics || 'T2' in topics) && !('T3' in topics)")
  .putData("body", "some data")
  .build();

String id = fcm.send(msg);

11. 管理客户端订阅

创建订阅:

fcm.subscribeToTopic(registrationTokens, topic);

⚠️ 重要:FCM不返回订阅ID,需自行维护订阅关系。

取消订阅:

fcm.unsubscribeFromTopic(Arrays.asList(registrationToken), topic);

12. 总结

本教程演示了在Spring Boot中集成Firebase Cloud Messaging实现消息推送的完整流程。完整代码见GitHub仓库