您的第一条使用 FCM 主题的多播推送消息

1. 简介

目标

在此 Codelab 中,您将学习如何对多平台应用进行插桩 (instrument),以便使用 FCM 主题向应用实例的各个子组多播推送消息。

完成后,您可以利用 FCM 基础架构管理这些子群组,并通过子群组进行多播推送消息。

主题概览

主题是一种支持 FCM 基础架构的方式,可通过消息覆盖应用实例的子群组。

FCM 提供用于发送消息以及维护对这些主题的订阅的 API。将应用实例与主题相关联和取消关联的行为分别称为订阅和退订

主题应该用于可公开访问的内容。例如,关于天气动态的消息。如果要发送用户敏感消息,请使用 Firebase Admin SDK 通过多台设备多播消息

基于主题的多播针对吞吐量进行了优化。

学习内容

  • 如何通过移动应用为用户订阅(和退订)主题。
  • 如何使用主题发送多播推送消息。
  • 如何使用主题条件向主题组合发送消息。
  • 如何在服务器端管理主题订阅以及如何进行批量订阅和取消订阅。

构建内容

  • 可以订阅/退订主题并在收到主题的消息时接收消息的 Android 应用。
  • 使用 Firebase Admin SDK 的服务器端集成,用于通过 FCM API 发送主题消息。

所需条件

  • 您选择的浏览器,例如 Chrome。
  • 用于开发 Java 应用的 IntelliJ IDEA IDE。
    • 请确保在安装时选择支持 Gradle。
  • 用于开发 Android 应用的 Android Studio IDE。
  • 一台运行 Android 应用的设备。以下两个字段之一:
    • Android 模拟器(需要在 Android Studio 中设置)。
    • 一台连接到计算机并设置为开发者模式的实体 Android 设备。
  • 一个用于创建和管理 Firebase 项目的 Google 帐号。

2. 准备工作

获取代码

从命令行克隆 GitHub 代码库:

git clone https://github.com/firebase/quickstart-android.git fcm-codelab

示例代码将克隆到 fcm-codelab 目录中。

cd fcm-codelab

此 Codelab 的起始应用位于 fcm-topics-codelab 分支的 messaging 目录中。如需获得起始代码,请按以下步骤操作。它包含两个目录:StockNewsAppStockNewsServer。前者包含起始 Android 应用,后者包含起始服务器端代码。

git checkout fcm-topics-codelab
cd messaging/fcm-topics-codelab/starter

此 Codelab 完成后的版本会放在 messaging/fcm-topics-codelab/completed 目录中。

创建 Firebase 项目

  1. Firebase 控制台中,点击添加项目,将 Firebase 项目命名为 StockNews,然后点击“继续”。注意:请记住您的 Firebase 项目的项目 ID(或点击修改图标,以设置偏好的项目 ID)。

fc08f9a7808e4553.png

  1. 您可以跳过启用 Google Analytics(分析)的步骤。在本 Codelab 中,您不需要它。点击继续
  2. 点击 Create project

恭喜!您刚刚创建了 Firebase 项目。现在,您可以点击项目名称进入控制台。

3. 针对具体平台的 Firebase 应用配置

启用 Firebase 支持所需的大部分代码更改都已签入您正在进行的项目中。不过,要添加对移动平台的支持,您需要:

  • 在 Firebase 项目中注册所需的平台
  • 下载针对具体平台的配置文件,并将其添加到代码中。

在此 Codelab 中,我们将添加一个 Android Firebase 应用。

84e0b3199bef6d8a配置 Android

  1. Firebase 控制台中,从“设置”齿轮图标中选择左侧导航栏顶部的项目设置,然后在“常规”页面中点击“您的应用”下的 Android 图标。

您应该会看到以下对话框:8254fc299e82f528.png

  1. 要提供的重要值是 Android 软件包名称。将其设置为 com.ticker.stocknews
    1. 此处提供的软件包名称必须与起始 StockNewsApp 起始代码的 AndroidManifest.xml 中提供的软件包名称相同。如果您想查找或更改它,请按以下步骤操作:
      1. StockNewsApp 目录中,打开文件 app/src/main/AndroidManifest.xml
      2. manifest 元素中,找到 package 属性的字符串值。这个值是 Android 软件包名称。
  1. 在 Firebase 对话框中,将复制的软件包名称粘贴到 Android 软件包名称字段中。
  2. 此 Codelab 不需要使用调试签名证书 SHA-1,因为此应用无法发布。请将此项留空。
  3. 点击注册应用
  4. 继续在 Firebase 控制台中,按照说明下载配置文件 google-services.json
  5. 您可以跳过其余设置步骤,因为所有其他设置都已在起始应用代码中进行配置。您会发现您的应用列在 Firebase 控制台的主页面上。
  6. 将您刚刚下载的 google-services.json 文件复制到 messaging/fcm-topics-codelab/starter/StockNewsApp/app 目录。

4.构建并运行您的应用

您已经准备就绪,可以真正开始开发应用了!首先,构建并运行应用。

导入 starter 应用

启动 Android Studio,然后从起始代码目录导入 messaging/fcm-topics-codelab/starter/StockNewsApp

项目加载后,您可能还会看到一条提醒,指出 Git 并未跟踪所有本地更改,您可以点击右上角的“Ignore”或“X”。(您不会将任何更改推送回 Git 代码库。)

如果您处于 Android 视图,那么在项目窗口的左上角应该会看到如下图所示的内容。(如果您处于 Project 视图,则需要展开项目才能看到同一内容)

b574ea0089ee87c6

请注意,首次打开项目时,Android Studio 可能需要数秒时间在后台编译项目。在此期间,您会在 Android Studio 底部的状态栏中看到一个旋转图标:

4bc64eb3b99eb0ae

我们建议您等到此过程完成后再更改代码。这样,Android Studio 就可以拉取所有必要的组件。

此外,如果您看到“重新加载使语言更改生效吗?”的提示或类似提示,请选择“是”。

模拟器设置

如果您在设置 Android 模拟器时需要帮助,请参阅运行应用一文。

了解 Android 应用起始代码

  • 起始代码是一个轻量级 Android 应用,具有最少的功能和界面。
  • firebase-messaging SDK 的依赖项已添加到 app/build.gradle 文件中。

F04ff8f48d186dff

  • AndroidManifest.xml 中,已经添加了 MESSAGING_EVENT 回调处理程序。
    • StockNewsMessagingService.java 这个处理程序扩展了 FirebaseMessagingService 类,该类提供了各种 Firebase Cloud Messaging 相关功能。如需了解详情,请参阅 FirebaseMessagingService 文档b843c4d33ee53166
    88fad1960f4a6ff5
    • 创建或刷新 FCM 注册令牌时,系统会调用 onNewToken 函数。如需了解详情,请参阅监控令牌的生成
    • 收到消息且应用在前台运行时,系统会调用 onMessageReceived 函数。目前,它仅记录收到的消息。
  • 此外,AndroidManifest.xml 中还提供了名为 StockNewsApplicationAndroid Applicationa4982a8731492dfc.pngccde692f7f68dc5a
    • 此类将是应用启动时要实例化的第一个类。
    • StockNewsApplication 类的 onCreate 函数中,添加了 FCM 注册令牌创建调用。系统会生成有效的 FCM 注册令牌并记录该令牌。
  • MainActivity.java 添加了用于显示股票类别选项的 RecyclerView
  • SubscriptionAdapter.java 会实现 RecyclerView.Adapter,用于绘制股票类别选择屏幕。
    • 每个股票类别都有一个名称,旁边有一个订阅切换开关。
    • 更改切换开关应发出 FCM 主题订阅 / 取消订阅调用。
    • 在接下来的部分中,您将实现这些调用。
  • model/StockCategories.java 类包含所有股票类别及其关联主题名称的列表。

b32663ec4e865a18.png

运行起始应用

  1. 将 Android 设备连接到计算机或启动模拟器。
  2. 在顶部的工具栏中,选择您的目标 Android 设备或模拟器,然后按运行按钮。

5b27fc5b237e06b9.png

  1. 应用界面将如下所示:

ff5b1a1c53231c54

  1. 应用将创建一个 FCM 注册令牌并记录该令牌。不过,应用界面不会发生任何变化。
    1. 复制并保存 FCM 注册令牌,因为将在后续步骤中使用。

927eb66bc909f36b

5. 发送测试消息

现在,您可以向您在上一步设置的应用实例发送测试消息了。

导入起始服务器代码

启动 IntelliJ IDEA 并打开 messaging/fcm-topics-codelab/starter/StockNewsServer 项目。

左侧导航栏中的项目视图应如下所示:

da20711f6527dff6

请注意,IntellIj IDEA 可能需要几分钟时间才能构建您的项目,包括拉取所需的依赖项。

了解服务器起始代码

  • 服务器起始代码是基于 Gradle 的 Java 项目。
  • build.gradle 文件已经添加了对 firebase-admin SDK 的依赖项。此 SDK 提供各种 FCM 消息发送功能。

650fc733298588f8

  • 最后,有两种类,即 viz:
    • FcmSender.java:此类包含以下值得注意的方法:
      • initFirebaseSDK:初始化 firebase-admin SDK。
      • sendMessageToFcmRegistrationToken:向 FCM 注册令牌发送消息。
      • sendMessageToFcmTopic:向 FCM 主题发送消息。
      • sendMessageToFcmTopicCondition:向 FCM 主题条件发送消息。
    • FcmSubscriptionManager.java:此类包含允许从服务器端管理主题订阅的方法。
      • initFirebaseSDK:初始化 firebase-admin SDK。
      • subscribeFcmRegistrationTokensToTopic:为 FCM 主题订阅 FCM 注册令牌。
      • unsubscribeFcmRegistrationTokensFromTopic:退订 FCM 主题中的 FCM 注册令牌。

设置服务器代码

  1. 首先,我们需要设置一个 Firebase 服务帐号,以便 firebase-admin SDK 能够授权调用 FCM API。
    1. 前往 Firebase 控制台,点击左侧导航栏中项目概览旁边的齿轮图标,然后选择项目设置8c2108d4d7c915e9.png
    2. 在设置页面中,选择服务账号,然后点击创建服务账号84b128cc5dac0a85
    3. 现在,点击 Generate new private key 按钮,系统会自动下载您的密钥文件。
    4. 将密钥文件重命名为 service-account.json,并将其复制到 messaging/fcm-topics-codelab/starter/StockNewsServer/src/main/resources 文件夹中。
    5. FcmSender.javaFcmSubscriptionManager.java 都使用以下代码从类路径加载 service-account.json 文件。8dffbee658e0bdd 图片
  2. 此时,服务器代码已准备就绪。从顶部菜单栏中运行 Build -> Build Project。

发送测试消息

  1. FcmSender.java 中,找到 sendMessageToFcmRegistrationToken 函数,然后将您从运行起始应用部分复制的 FCM 注册令牌插入 registrationToken 字段。
  2. main 函数中,仅取消注释 sendMessageToFcmRegistrationToken 函数,然后点击“运行”以执行代码。
    1. 观察在 message 对象的 Token 字段中设置 FCM 注册令牌的情况。
    2. 此外,请注意我们如何使用 FirebaseMessaging 接口的 send API。

52e4a3ec3f816473

  1. 这应该会向您在上一步中设置的应用实例发送一条消息。
  2. 当应用实例处于前台时,您应该会看到消息内容被记录。

d3540ec1089f97dd.png

  1. 当该应用实例在后台运行时,您会看到消息显示在通知栏中。

31203deca59c03fe

太棒了,您使用 Firebase Admin SDK 向应用实例发送消息。详细了解如何在服务器中使用 Firebase Admin SDK

6. 实现主题订阅 / 取消订阅

在此步骤中,您将在 Android 应用的“股票类别”切换开关上实现主题订阅和退订操作。

当应用用户切换特定股票类别的开关时,将发出主题订阅或取消订阅调用。

查看代码

  • 转到 Android 应用代码中的 SubscriptionAdapter.java 类,并找到 RecyclerViewViewHolder 类。

6c0614199e684f6

  • 类构造函数使用 setOnCheckedChangeListener 为订阅切换开关设置监听器。
  • 根据切换开关,可以分别通过调用 subscribeToStockCategoryunsubscribeFromStockCategory 方法来执行订阅和退订操作。
  • RecyclerView 适配器的 onBindViewHolder 会调用 setData 方法,以将 ViewHolder 与相应的库存类别绑定。

实现主题订阅

  1. subscribeToStockCategory 方法中,您将实现对 FirebaseMessaging 对象的 subscribeToTopic API 的调用。代码可能如下所示:
   void subscribeToStockCategory() {
      // Making call to FCM for subscribing to the topic for stockCategory
     FirebaseMessaging.getInstance().subscribeToTopic(stockCategory.getTopicName()).addOnSuccessListener(
          unused -> {
            // Subscribing action successful
            Log.i(TAG, "Subscribed to topic: " + stockCategory.getTopicName());
            Toast.makeText(itemView.getContext(), "Subscribed to " + stockCategory.getCategoryName(),
                Toast.LENGTH_SHORT).show();
          });
    }

实现主题退订

  1. 同样,在 else 条件中,您将实现对 unsubscribeFromTopic API 的调用。类似以下内容:
void unsubscribeFromStockCategory() {
      // Making call to FCM for unsubscribing from the topic for stockCategory
      FirebaseMessaging.getInstance().unsubscribeFromTopic(stockCategory.getTopicName())
          .addOnSuccessListener(unused -> {
            // Unsubscribing action successful
            Log.i(TAG, "Unsubscribed from topic: " + stockCategory.getTopicName());
            Toast.makeText(itemView.getContext(), "Unsubscribed from " + stockCategory.getCategoryName(),
                Toast.LENGTH_SHORT).show();
          });
    }

我们来试试

  1. 运行应用并切换 Stock Category 选项以执行 Subscribe 和 Unsubscribe 操作。这如下所示:

订阅

退订

7. 发送您的第一条主题消息

在此步骤中,您将实现服务器端代码以发送 FCM 主题消息。

实现用于发送主题消息的服务器端集成

  1. 在服务器代码中,跳转到 FcmSender.java 并找到名为 sendMessageToFcmTopic 的方法。

56381dd1b40cde9c

  1. 在第一行中,提供您要将消息发送到的 FCM 主题。
    • 该字符串是一个字符串,格式为:/topics/<Topic Name>。例如 /topics/Technology
  2. 在接下来的几行中,创建一个新的 message 对象(类似于 sendMessageToFcmRegistrationToken 函数中定义的对象)。
    • 不同之处在于,您不是设置 message 对象的 Token 字段,而是设置 Topic 字段。
Message message = Message.builder()
        .putData("FOOTECH", "$1000")
        .setNotification(
            Notification.builder()
                .setTitle("Investor confidence in Tech Stocks growing")
                .setBody("Foo Tech leading the way in stock growth for Tech sector.")
                .build())
        .setTopic(topicName)
        .build();
  1. 现在,添加对 FirebaseMessaging 实例的调用以发送消息(与 sendMessageToFcmRegistrationToken 函数中进行的 send 调用相同)。
FirebaseMessaging.getInstance().send(message);
  1. 最后,更新 main 函数并仅允许调用 sendMessageToFcmTopic 函数。

9a6aa08dd7c28898

发送消息并验证收到

  1. 发送主题消息之前,请先确保您的应用实例已订阅您要发送到的主题。
    1. 翻转相应的切换开关即可完成此操作。例如:
    4668247408377712
  2. 现在,您可以通过执行 FcmSender.javamain 函数来发送主题消息。
  3. 和之前一样,您应该能够观察应用实例上的消息接收情况。
    1. 前台应用实例
    c144721399f610fe
    1. 后台应用实例
    44efc7dfd57e8e9a.png
  4. 额外好处:请尝试退订您收到的主题,然后重新发送邮件。您会看到消息未传送到应用实例。

8. 发送您的第一条主题条件消息

通过主题条件功能,您可以向主题组合发送消息,以便提供更具表现力的受众群体定义。

例如,在我们的 StockNews 应用中,考虑是否能够向一组订阅了技术或汽车主题的应用实例发送消息。例如,当发生涉及 Waymo 的值得注意的事件时,就会出现这种情况。

Topics 允许您使用以下运算符,以布尔表达式的形式来表达您的组合

  • &&:逻辑与。例如,'Technology' in topics && 'Automotive' in topics - 仅定位同时订阅了技术和汽车主题的应用实例。
  • ||:逻辑 OR。例如,'Technology' in topics || 'Automotive' in topics - 定位订阅了技术或汽车主题的应用实例。
  • ():用于分组的圆括号。例如,'Technology' in topics && ('Automotive' in topics || 'Energy' in topics) - 仅定位已订阅“Tech”以及“Auto”或“Energy”主题的应用实例。

详细了解如何构建发送请求以使用此功能。

实现用于发送主题条件消息的服务器端集成

  1. 返回服务器代码,跳转到 FcmSender.java 并找到名为 sendMessageToFcmTopicCondition 的方法。

3719a86c274522cf.png

  1. 在第一行中,对于 topicCondition 变量,请提供要将消息发送到的主题条件。你可以将其设置为:'Technology' in topics && 'Automotive' in topics
  2. 在接下来的几行中,创建一个新的 message 对象(类似于 sendMessageToFcmTopic 函数中定义的对象)。
    1. 不同之处在于,您将设置 Condition 字段,而不是设置对象的 Topic 字段。
    Message message = Message.builder()
        .putData("FOOCAR", "$500")
        .setNotification(
            Notification.builder()
                .setTitle("Foo Car shows strong Q2 results")
                .setBody("Foo Car crosses 1B miles. Stocks rally.")
                .build())
        .setCondition(topicCondition)
        .build();
  1. 现在,添加对 FirebaseMessaging 实例的调用以发送消息(与 sendMessageToFcmTopic 函数中进行的 send 调用相同)。
FirebaseMessaging.getInstance().send(message);
  1. 最后,更新 main 函数并仅允许调用 sendMessageToFcmTopicCondition 函数。

db9588d40d2a0da6.png

发送消息并验证接收

  1. 在发送主题消息之前,请先为应用实例订阅技术和汽车主题,以确保应用实例满足指定的主题条件。
  2. 现在,您可以通过执行 FcmSender.javamain 函数来发送主题消息。
  3. 与之前一样,您应该能够在应用实例上观察消息接收情况。
    1. 前台应用实例
    6f612ace15aa6515
    1. 后台应用实例
    78044a56ac2359cb.png
  4. 额外好处:您现在可以退订“技术”主题,并重新发送主题条件消息。您应该会发现,应用实例未收到消息。

9. 要点回顾

让我们快速回顾一下您目前所学的内容。

  • 如何从应用实例启动主题订阅 / 退订。
  • 向主题发送消息并验证在已订阅的应用实例上接收的消息。
  • 向主题条件发送消息,并在满足条件的应用实例上验证接收。

在下一部分中,您将学习如何让应用实例订阅 / 退订主题,而无需实例化来自客户端的调用。

c0dc20655d392690.gif

10. 从服务器端管理主题订阅

到目前为止,在此 Codelab 中,所有主题订阅和退订调用都是从应用实例发起的。

但在某些用例中,您可能需要从服务器端管理主题订阅。例如,您可能希望现有用户群组的某个子群组订阅新主题,而无需等待应用发布。

在本部分,您将了解如何使用 Firebase Admin SDK 通过从服务器端调用来为主题订阅和退订一批 FCM 注册令牌。

实现针对 FCM 主题的 FCM 注册令牌的服务器端订阅

  1. 在服务器代码中,跳转到 FcmSubscriptionManager.java 类。找到名为 subscribeFcmRegistrationTokensToTopic 的方法。您将在此处实现对 subscribeToTopic API 的调用。

5d5709e7b3cbcb04

  1. 让我们为应用实例订阅 Energy 主题。为此,请先为以下两个字段提供数据:
    1. registrationTokens:一个以英文逗号分隔的字符串列表,表示您要为其创建主题订阅的 FCM 注册令牌。
    2. topicName:Energy 主题的主题名称,即 /topics/Energy
  2. 在接下来的几行中,按以下方式实现该调用:
TopicManagementResponse response = FirebaseMessaging.getInstance().subscribeToTopic(
        registrationTokens, topicName);
  1. 您可以检查 TopicManagementResponse,获取一些概要结果统计信息。例如,使用 getSuccessCount 输出成功创建的主题订阅的数量。
System.out.printf("Num tokens successfully subscribed %d", response.getSuccessCount());
  1. 最后,在 main 函数中,仅启用对 subscribeFcmRegistrationTokensToTopic 函数的调用。

创建订阅并发送主题消息

  1. 此时,您可以创建主题订阅并向其发送消息。
  2. 执行 FcmSubscriptionManager.java 类的 main 函数。这将创建一个主题订阅。
  3. 现在,设置用于发送消息的代码。与之前一样,
    1. FcmSender.java 中,找到 sendMessageToFcmTopic 函数。
    2. topicName 设置为“能耗”主题,即/topics/Energy
    3. 创建一个 Message 对象,并使用 setTopic 将其定位到该主题。
    4. 最后,更新 main 方法以仅启用 sendMessageToFcmTopic 函数。
  4. 执行 FcmSender.javamain 函数。这会将消息发送到您的应用实例,您可以在应用中观察它,如下所示。
    1. 前台应用实例
    40ab6cf71e0e4116
    1. 后台应用实例
    8fba81037198209e.png

为 FCM 主题实现服务器端退订 FCM 注册令牌

  1. 对于服务器端主题退订,请使用此 unsubscribeFromTopic API。您将向 FcmSubscriptionManager.java 类的 unsubscribeFcmRegistrationTokensFromTopic 函数添加相关代码。

8d9e8ea9d34016bd

  1. 实现服务器端取消订阅代码并通过发送主题消息验证其效果,则需要您做练习。

11. 恭喜

恭喜,您已成功使用 FCM 主题向应用实例的子群组发送多播消息。这有助于简化您及时向用户提供相关内容的能力。

947def3eb33b1e4a.gif

后续步骤

您已完成此 Codelab 的学习,接下来不妨考虑按照以下指南尝试针对其他平台的主题:

参考文档