Firebase Cloud Messaging 使用入门


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

Firebase Cloud Messaging 和 Android 使用入门

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

设置 SDK

将 Firebase 添加到您的 Android 项目(如果尚未添加)。

为了获得最佳的 FCM 使用体验,我们强烈建议您在项目中启用 Google AnalyticsFCM消息传送报告功能需要使用 Google Analytics

修改您的应用清单

将以下内容添加至应用的清单中:

  • 一项扩展 FirebaseMessagingService 的服务。除了接收通知外,如果您还希望在后台应用中进行消息处理,则必须添加此服务。例如,您需要在前台应用中接收通知、接收数据载荷等,就必须扩展此服务。
  • <service     android:name=".java.MyFirebaseMessagingService"     android:exported="false">     <intent-filter>         <action android:name="com.google.firebase.MESSAGING_EVENT" />     </intent-filter> </service>
  • (可选)应用组件中用于设置默认通知图标和颜色的元数据元素。如果传入的消息未明确设置图标和颜色,Android 就会使用这些值。
  • <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.      See README(https://goo.gl/l4GJaQ) for more. --> <meta-data     android:name="com.google.firebase.messaging.default_notification_icon"     android:resource="@drawable/ic_stat_ic_notification" /> <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming      notification message. See README(https://goo.gl/6BKBk7) for more. --> <meta-data     android:name="com.google.firebase.messaging.default_notification_color"     android:resource="@color/colorAccent" />
  • (可选)从 Android 8.0(API 级别 26)和更高版本开始,我们支持并推荐使用通知渠道FCM 提供具有基本设置的默认通知渠道。如果您希望创建和使用自己的默认渠道,请将 default_notification_channel_id 设置为您的通知渠道对象的 ID(如下所示);只要传入的消息未明确设置通知渠道,FCM 就会使用此值。如需了解详情,请参阅管理通知渠道
  • <meta-data     android:name="com.google.firebase.messaging.default_notification_channel_id"     android:value="@string/default_notification_channel_id" />

在 Android 13 及更高版本上请求运行时通知权限

Android 13 中引入了用于显示通知的新运行时权限。该项引入会影响在 Android 13 或更高版本上使用 FCM 通知的所有应用。

默认情况下,FCM SDK(23.0.6 或更高版本)中包含清单中定义的 POST_NOTIFICATIONS 权限。不过,您的应用还需要通过常量 android.permission.POST_NOTIFICATIONS 请求此权限的运行时版本。在用户授予此权限之前,您的应用将无法显示通知。

如需请求该项新运行时权限,请执行以下操作:

Kotlin

// Declare the launcher at the top of your Activity/Fragment: private val requestPermissionLauncher = registerForActivityResult(     ActivityResultContracts.RequestPermission(), ) { isGranted: Boolean ->     if (isGranted) {         // FCM SDK (and your app) can post notifications.     } else {         // TODO: Inform user that that your app will not show notifications.     } }  private fun askNotificationPermission() {     // This is only necessary for API level >= 33 (TIRAMISU)     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {         if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==             PackageManager.PERMISSION_GRANTED         ) {             // FCM SDK (and your app) can post notifications.         } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {             // TODO: display an educational UI explaining to the user the features that will be enabled             //       by them granting the POST_NOTIFICATION permission. This UI should provide the user             //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.             //       If the user selects "No thanks," allow the user to continue without notifications.         } else {             // Directly ask for the permission             requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)         }     } }

Java

// Declare the launcher at the top of your Activity/Fragment: private final ActivityResultLauncher<String> requestPermissionLauncher =         registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {             if (isGranted) {                 // FCM SDK (and your app) can post notifications.             } else {                 // TODO: Inform user that that your app will not show notifications.             }         });  private void askNotificationPermission() {     // This is only necessary for API level >= 33 (TIRAMISU)     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {         if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==                 PackageManager.PERMISSION_GRANTED) {             // FCM SDK (and your app) can post notifications.         } else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {             // TODO: display an educational UI explaining to the user the features that will be enabled             //       by them granting the POST_NOTIFICATION permission. This UI should provide the user             //       "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.             //       If the user selects "No thanks," allow the user to continue without notifications.         } else {             // Directly ask for the permission             requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);         }     } }

通常,您应向用户显示一个界面,说明如果用户授予应用发布通知的权限,会启用哪些功能。此界面应向用户提供同意或拒绝的选项,例如确定不用了按钮。如果用户选择确定,则直接请求该权限。如果用户选择不用了,则允许用户在不接收通知的情况下继续操作。

如需详细了解有关您的应用应在何时向用户请求 POST_NOTIFICATIONS 权限的最佳实践,请参阅通知运行时权限

使用 Android 12L(API 级别 32)或更低版本的应用上的通知权限

当您的应用首次创建通知渠道时,只要应用处于前台,Android 便会自动请求用户授予该权限。不过,关于创建渠道和请求权限的时机,需要注意下面一些重要事项:

  • 如果您的应用是在后台运行时创建的第一个通知渠道(FCM SDK 在收到 FCM 通知时便会在后台创建通知渠道),Android 不会允许该通知显示出来,并且直到用户下次打开应用时才会提示他们授予通知权限。这意味着,在用户打开应用并授予该权限之前收到的所有通知都将丢失。
  • 我们强烈建议您将应用更新为使用 Android 13 及更高版本,以便能够利用平台的 API 来请求权限。如果您无法进行此更新,您的应用应该在您向其发送任何通知之前创建通知渠道,以便触发通知权限对话框,并确保不会丢失通知。如需了解详情,请参阅通知权限最佳实践

可选:移除 POST_NOTIFICATIONS 权限

默认情况下,FCM SDK 包含 POST_NOTIFICATIONS 权限。如果您的应用不使用通知消息(无论是通过 FCM 通知、通过其他 SDK 还是由您的应用直接发布),并且您不想让应用包含该权限,则可以使用清单合并remove 标记移除该权限。请注意,移除此权限会阻止系统显示所有通知,而不仅仅是 FCM 通知。将以下内容添加到应用的清单文件中:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" tools:node="remove"/> 

获取设备注册令牌

初次启动您的应用时,FCM SDK 会为客户端应用实例生成一个注册令牌。如果您希望指定单一目标设备或者创建设备组,需要扩展 FirebaseMessagingService 并重写 onNewToken 来获取此令牌。 因为令牌可能会在初始启动后轮替,所以我们强烈建议您检索最近更新的注册令牌。

注册令牌可能会在发生下列情况时更改:

  • 应用在新设备上恢复
  • 用户卸载/重新安装应用
  • 用户清除应用数据。

检索当前注册令牌

如果需要检索当前令牌,请调用 FirebaseMessaging.getInstance().getToken()

Kotlin

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->     if (!task.isSuccessful) {         Log.w(TAG, "Fetching FCM registration token failed", task.exception)         return@OnCompleteListener     }      // Get new FCM registration token     val token = task.result      // Log and toast     val msg = getString(R.string.msg_token_fmt, token)     Log.d(TAG, msg)     Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show() })

Java

FirebaseMessaging.getInstance().getToken()     .addOnCompleteListener(new OnCompleteListener<String>() {         @Override         public void onComplete(@NonNull Task<String> task) {           if (!task.isSuccessful()) {             Log.w(TAG, "Fetching FCM registration token failed", task.getException());             return;           }            // Get new FCM registration token           String token = task.getResult();            // Log and toast           String msg = getString(R.string.msg_token_fmt, token);           Log.d(TAG, msg);           Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();         }     });

监控令牌的生成

每当生成新令牌时,都会触发 onNewToken 回调函数。

Kotlin

/**  * Called if the FCM registration token is updated. This may occur if the security of  * the previous token had been compromised. Note that this is called when the  * FCM registration token is initially generated so this is where you would retrieve the token.  */ override fun onNewToken(token: String) {     Log.d(TAG, "Refreshed token: $token")      // If you want to send messages to this application instance or     // manage this apps subscriptions on the server side, send the     // FCM registration token to your app server.     sendRegistrationToServer(token) }

Java

/**  * There are two scenarios when onNewToken is called:  * 1) When a new token is generated on initial app startup  * 2) Whenever an existing token is changed  * Under #2, there are three scenarios when the existing token is changed:  * A) App is restored to a new device  * B) User uninstalls/reinstalls the app  * C) User clears app data  */ @Override public void onNewToken(@NonNull String token) {     Log.d(TAG, "Refreshed token: " + token);      // If you want to send messages to this application instance or     // manage this apps subscriptions on the server side, send the     // FCM registration token to your app server.     sendRegistrationToServer(token); }

获取令牌后,可以将其发送到您的应用服务器,并使用您首选的方法进行存储。

检查 Google Play 服务

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

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

防止自动初始化

在生成 FCM 注册令牌后,库会将标识符和配置数据上传到 Firebase。如果您希望阻止自动生成令牌,请将以下元数据值添加到 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 自动初始化功能,请执行运行时调用:

Kotlin

Firebase.messaging.isAutoInitEnabled = true

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

如需重新启用 Analytics 数据收集,请调用 FirebaseAnalytics 类的 setAnalyticsCollectionEnabled() 方法。例如:

setAnalyticsCollectionEnabled(true); 

这些值一经设置,即使应用重启也将持续生效。

发送通知消息

如要确保 Android 客户端设置正确,您可以按照以下说明发送测试通知消息:

  1. 在目标设备上安装并运行该应用。
  2. 确保应用在设备的后台中运行。
  3. Firebase 控制台中,打开“Messaging”(消息传递)页面。
  4. 如果这是您的第一条消息,请依次选择创建首个宣传活动Firebase 通知消息创建
  5. 否则,请在宣传活动标签页上选择新建宣传活动,然后选择通知
  6. 输入消息内容。所有其他字段都是选填字段。
  7. 从右侧窗格中选择发送测试消息
  8. 在标签为添加 FCM 注册令牌的字段中,输入您根据本指南的前一部分获得的注册令牌。
  9. 选择测试

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

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

后续步骤

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