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

一、简介

目标

在此 Codelab 中,您将学习如何检测多平台应用程序,以便可以使用 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 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. 单击创建项目

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

3. 特定于平台的 Firebase 应用配置

启用 Firebase 支持所需的大部分代码更改已签入您正在处理的项目中。但是,为了添加对移动平台的支持,您需要:

  • 在 Firebase 项目上注册所需的平台
  • 下载特定于平台的配置文件,并将其添加到代码中。

出于本 Codelab 的目的,我们将添加一个 Android Firebase 应用。

84e0b3199bef6d8a.png配置安卓

  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. 构建并运行您的应用程序

您已准备好真正开始开发您的应用程序了!首先,构建并运行应用程序。

导入入门应用程序

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

项目加载后,您可能还会看到一条警告,指出 Git 未跟踪所有本地更改,您可以单击“忽略”或右上角的“ X ”。 (您不会将任何更改推送回 Git 存储库。)

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

b574ea0089ee87c6.png

请注意,Android Studio 首次在后台编译项目可能需要几秒钟的时间。在此期间,您将在 Android Studio 底部的状态栏中看到一个微调器:

4bc64eb3b99eb0ae.png

我们建议您等到此操作完成后再进行代码更改。这将允许 Android Studio 引入所有必要的组件。

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

模拟器设置

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

了解Android App启动代码

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

f04ff8f48d186dff.png

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

b32663ec4e865a18.png

运行启动应用程序

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

5b27fc5b237e06b9.png

  1. 应用程序 UI 将如下所示:

ff5b1a1c53231c54.png

  1. 该应用程序将创建 FCM 注册令牌并记录它。但是应用程序 UI 不会发生任何变化。
    1. 复制并保存 FCM 注册令牌,因为它将在后续步骤中使用。

927eb66bc909f36b.png

5. 发送测试消息

现在您已准备好向您在上一步中设置的应用程序实例发送测试消息。

导入启动服务器代码

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

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

da20711f6527dff6.png

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

了解服务器启动代码

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

650fc733298588f8.png

  • 最后,有两个类,即:
    • 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.png
    3. 现在单击“生成新的私钥”按钮,将开始自动下载密钥文件。
    4. 将密钥文件重命名为service-account.json并将其复制到messaging/fcm-topics-codelab/starter/StockNewsServer/src/main/resources文件夹中。
    5. FcmSender.javaFcmSubscriptionManager.java使用以下代码从类路径加载service-account.json文件。 8dffbee658e0bdd.png
  2. 至此,服务端代码就准备好了。从顶部菜单栏运行“构建”->“构建项目”。

发送测试消息

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

52e4a3ec3f816473.png

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

d3540ec1089f97dd.png

  1. 当应用程序实例处于后台时,您会看到通知托盘中出现该消息。

31203deca59c03fe.png

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

6.实现主题订阅/退订

在此步骤中,您将在 Android 应用程序的股票类别切换上实现主题订阅和取消订阅操作。

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

审查代码

  • 导航到 Android 应用程序代码中的SubscriptionAdapter.java类并找到RecyclerViewViewHolder类。

6c0614199e684f6.png

  • 类构造函数使用setOnCheckedChangeListener为订阅切换设置侦听器。
  • 根据开关切换,订阅和取消订阅操作分别通过调用subscribeToStockCategoryunsubscribeFromStockCategory方法来执行。
  • setData方法由 RecyclerView Adapter 的onBindViewHolder调用,以将 ViewHolder 与适当的 Stock Category 绑定。

实现主题订阅

  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. 运行应用程序并切换股票类别选项以执行订阅和取消订阅操作。它看起来像这样:

订阅

退订

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

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

实现服务器端集成以发送主题消息

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

56381dd1b40cde9c.png

  1. 在第一行中,提供您要将消息发送到的 FCM 主题。
    • 它是一个以下形式的字符串: /topics/<Topic Name> 。例如, /topics/Technology
  2. 在下一行中创建一个新的message对象(类似于sendMessageToFcmRegistrationToken函数中定义的对象)。
    • 不同之处在于,您将设置Token字段,而不是设置message对象的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函数中进行的发送调用相同)。
FirebaseMessaging.getInstance().send(message);
  1. 最后,更新main函数并启用仅调用sendMessageToFcmTopic函数。

9a6aa08dd7c28898.png

发送消息并验证接收

  1. 在发送主题消息之前,首先确保您的应用实例已订阅您要发送到的主题。
    1. 这可以通过翻转相应的开关来完成。例如:
    4668247408377712.png
  2. 您现在可以通过执行FcmSender.javamain函数来发送主题消息。
  3. 像以前一样,您应该能够观察应用程序实例上的消息接收。
    1. 前台应用程序实例
    c144721399f610fe.png
    1. 后台应用程序实例
    44efc7dfd57e8e9a.png
  4. 奖励:尝试取消订阅您发送到的主题并重新发送消息。您会发现消息没有传递到应用程序实例。

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

主题条件功能允许您将消息发送到主题组合,从而使您能够提供更具表现力的受众定义。

例如,在我们的 StockNews 应用程序中,考虑向订阅技术或汽车主题的一组应用程序实例发送消息的可能性。例如,如果发生涉及 Waymo 的值得注意事件,则可能会发生这种情况。

主题允许您使用以下运算符以布尔表达式的形式表达您的组合

  • && :逻辑与。例如, 'Technology' in topics && 'Automotive' in topics - 仅定位订阅技术和汽车主题的应用程序实例。
  • || :逻辑或。例如, 'Technology' in topics || 'Automotive' in topics - 定位订阅技术或汽车主题的应用程序实例。
  • () :用于分组的括号。例如, 'Technology' in topics && ('Automotive' in topics || 'Energy' in topics) - 仅定位订阅技术以及汽车或能源主题的应用程序实例。

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

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

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

3719a86c274522cf.png

  1. 在第一行中,对于topicCondition变量,提供要将消息发送到的主题条件。您可以将其设置为: 'Technology' in topics && 'Automotive' in topics
  2. 在接下来的行中,创建一个新的message对象(类似于sendMessageToFcmTopic函数中定义的对象)。
    1. 区别在于您将设置Topic字段,而不是设置对象的Condition字段。
    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函数中进行的发送调用相同)。
FirebaseMessaging.getInstance().send(message);
  1. 最后,更新main函数并启用仅调用sendMessageToFcmTopicCondition函数。

db9588d40d2a0da6.png

发送消息并验证接收

  1. 在发送主题消息之前,首先通过订阅技术和汽车主题来确保您的应用实例满足指定的主题条件。
  2. 您现在可以通过执行FcmSender.javamain函数来发送主题消息。
  3. 像以前一样,您应该能够观察应用程序实例上的消息接收。
    1. 前台应用程序实例
    6f612ace15aa6515.png
    1. 后台应用程序实例
    78044a56ac2359cb.png
  4. 奖励:您现在可以取消订阅技术主题并重新发送主题条件消息。您应该观察到应用程序实例没有收到该消息。

9. 回顾

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

  • 如何从应用实例发起主题订阅/取消订阅。
  • 向主题发送消息并验证订阅的应用程序实例的接收。
  • 向主题条件发送消息并验证满足条件的应用程序实例上的接收。

在下一节中,您将了解如何订阅/取消订阅应用程序实例的主题,而无需从客户端实例化调用。

c0dc20655d392690.gif

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

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

但是,在某些用例中,您可能希望从服务器端管理主题订阅。例如,您可能希望为现有用户群的一部分订阅新主题,而无需等待应用程序推出。

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

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

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

5d5709e7b3cbcb04.png

  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设置为 Energy 主题,即/topics/Energy
    3. 创建一个Message对象并使用setTopic将其定位到主题。
    4. 最后,更新main方法以仅启用sendMessageToFcmTopic功能。
  4. 执行FcmSender.javamain函数。这会将消息发送到您的应用程序实例,您可以在应用程序中观察它,如下所示。
    1. 前台应用程序实例
    40ab6cf71e0e4116.png
    1. 后台应用程序实例
    8fba81037198209e.png

实施服务器端取消订阅 FCM 注册令牌到 FCM 主题

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

8d9e8ea9d34016bd.png

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

11.恭喜你

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

947def3eb33b1e4a.gif

下一步是什么?

现在您已经完成了 Codelab,请考虑使用以下指南尝试其他平台的主题:

参考文档