Firebase Cloud Messaging 使用入门


本快速入门介绍了如何在移动和 Web 客户端应用中设置 Firebase Cloud Messaging,以便您能够可靠地发送消息。对于服务器环境,请参阅您的服务器环境和 FCM

设置 Firebase Cloud Messaging 客户端应用 (Flutter)

根据您的目标平台,您还需要执行一些额外的必要设置步骤。

iOS+

方法调配

如要在 Apple 设备上使用 FCM Flutter 插件,则必须进行方法调配。如果不进行方法调配,一些关键的 Firebase 功能(如 FCM 令牌处理)将无法正常工作。

Android

Google Play 服务

FCM 客户端需要在搭载 Android 4.4 或更高版本且安装了 Google Play 服务的设备上运行,或者在搭载 Android 4.4 版本且支持 Google API 的模拟器中运行。请注意,除了使用 Google Play 商店,您还可以通过其他方式部署您的 Android 应用。

依靠 Play 服务 SDK 运行的应用在访问 Google Play 服务功能之前,应始终检查设备是否拥有兼容的 Google Play 服务 APK。我们建议您在以下两个位置进行检查:主 activity 的 onCreate() 方法和 onResume() 方法。在 onCreate() 中检查可确保该应用在检查成功之前无法使用。在 onResume() 中检查可确保当用户通过一些其他方式(比如返回按钮)返回正在运行的应用时,仍会执行检查。

如果设备没有兼容的 Google Play 服务版本,您的应用可以调用 GoogleApiAvailability.makeGooglePlayServicesAvailable(),以便用户从 Play 商店下载 Google Play 服务。

Web

FCM 配置 Web 凭据

FCM 网页界面使用名为“自主应用服务器标识”(即“VAPID”密钥)的 Web 凭证来授权向支持的 Web 推送服务发送请求。如需为应用订阅推送通知,您需要将一对密钥与您的 Firebase 项目相关联。您可以生成新的密钥对,也可以通过 Firebase 控制台导入现有的密钥对。

安装 FCM 插件

  1. 安装并初始化适用于 Flutter 的 Firebase 插件(如果您尚未这样做)。

  2. 从 Flutter 项目的根目录运行以下命令,以安装该插件:

    flutter pub add firebase_messaging
    
  3. 完成后,重新构建您的 Flutter 应用:

    flutter run
    

获取注册令牌

如要将消息发送到特定的设备,您需要知道该设备的注册令牌。如需检索应用实例的注册令牌,请调用 getToken()。如果未授予通知权限,此方法将向用户请求通知权限。在其他情况下,它会返回一个令牌,或由于出现错误而拒绝该 Future。

// You may set the permission requests to "provisional" which allows the user to choose what type
// of notifications they would like to receive once the user receives a notification.
final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true);

// For apple platforms, make sure the APNS token is available before making any FCM plugin API calls
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
 // APNS token is available, make FCM plugin API requests...
}

在 Web 平台上,将您的 VAPID 公钥传递给 getToken()

final fcmToken = await FirebaseMessaging.instance.getToken(vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu");

如需在每次令牌更新时获得通知,请订阅 onTokenRefresh 流:

FirebaseMessaging.instance.onTokenRefresh
    .listen((fcmToken) {
      // TODO: If necessary send token to application server.

      // Note: This callback is fired at each app startup and whenever a new
      // token is generated.
    })
    .onError((err) {
      // Error getting token.
    });

防止自动初始化

在生成 FCM 注册令牌后,库会将标识符和配置数据上传到 Firebase。如果您希望阻止自动生成令牌,请在构建时停用自动初始化功能。

iOS

在 iOS 上,向您的 Info.plist 添加元数据值:

FirebaseMessagingAutoInitEnabled = NO

Android

在 Android 上,通过将以下元数据值添加到 AndroidManifest.xml 来停用 Analytics 数据收集和 FCM 自动初始化功能(您必须同时停用这两项功能):

<meta-data
    android:name="firebase_messaging_auto_init_enabled"
    android:value="false" />
<meta-data
    android:name="firebase_analytics_collection_enabled"
    android:value="false" />

在运行时重新启用 FCM 自动初始化功能

如需为特定应用实例启用自动初始化功能,请调用 setAutoInitEnabled()

await FirebaseMessaging.instance.setAutoInitEnabled(true);

此值一经设置便会持久保存,不受应用重启的影响。

发送测试通知消息

  1. 在目标设备上安装并运行该应用。在 Apple 设备上,您需要接受权限请求,才能收到远程通知。
  2. 确保应用在设备的后台运行。
  3. 在 Firebase 控制台中,打开“Messaging”(消息传递)页面。
  4. 如果这是您的第一条消息,请选择创建首个宣传活动
    1. 选择 Firebase 通知消息,然后选择创建
  5. 否则,请在宣传活动标签页上选择新建宣传活动,然后选择通知
  6. 输入消息内容。
  7. 从右侧窗格中选择发送测试消息
  8. 在标签为添加 FCM 注册令牌的字段中,输入您的注册令牌。
  9. 选择测试

在您选择测试后,目标客户端设备(其应用在后台运行)应该会接收到通知。

如需详细了解发送到您应用的消息,请参阅 FCM 报告信息中心。该信息中心会记录在 Apple 和 Android 设备上发送和打开的消息数量,以及 Android 应用的展示次数数据。

处理交互

当用户点按通知时,Android 和 iOS 上的默认行为均是打开应用。也就是说,如果应用当前是终止状态,系统便会启动应用;如果应用在后台运行,系统则会将其转至前台。

根据通知的具体内容,您可能会希望在应用打开时便处理用户与通知的交互。例如,如果系统通过通知发送了新的聊天消息并且用户选择了该消息,那么您可能会希望应用在打开时便同时打开具体对话内容。

firebase-messaging 软件包提供了两种方式来处理此类交互:

  1. getInitialMessage()::如果应用在打开之前处于终止状态,则此方法会返回一个包含 RemoteMessageFuture,并且系统会在用户使用该 RemoteMessage 之后将其移除。
  2. onMessageOpenedApp:如果应用在打开之前处于后台状态,则系统会通过一个 Stream 来发布 RemoteMessage

您应按上述方式处理这两种情况,以确保用户获得顺畅的体验。以下代码示例简单展示了实现上述操作的方法:

class Application extends StatefulWidget {
  @override
  State createState() => _Application();
}

class _Application extends State {
  // In this example, suppose that all messages contain a data field with the key 'type'.
  Future setupInteractedMessage() async {
    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage? initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage != null) {
      _handleMessage(initialMessage);
    }

    // Also handle any interaction when the app is in the background using a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
  }

  void _handleMessage(RemoteMessage message) {
    if (message.data['type'] == 'chat') {
      Navigator.pushNamed(context, '/chat',
        arguments: ChatArguments(message),
      );
    }
  }

  @override
  void initState() {
    super.initState();

    // Run code required to handle interacted messages in an async function
    // as initState() must not be async
    setupInteractedMessage();
  }

  @override
  Widget build(BuildContext context) {
    return Text("...");
  }
}

具体使用哪一种交互处理方式取决于您的设置。前面展示的是一个使用 StatefulWidget 的基本示例。

后续步骤

完成设置步骤后,您可以通过以下几个选项继续了解 Flutter 版 FCM