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

如需使用 Unity 编写跨平台 Firebase Cloud Messaging 客户端应用,请使用 Firebase Cloud Messaging API。Unity SDK 在 Android 和 Apple 平台中都可使用,但需要针对每个平台进行一些额外设置。

准备工作

前提条件

  • 安装 Unity 2021 LTS 或更高版本。对 Unity 2020 的支持被视为已弃用,并将在下一个主要版本之后不再享受积极支持。更早的版本也可能兼容,但不享受积极支持。

  • (仅限 Apple 平台)安装以下各项:

    • Xcode 13.3.1 或更高版本
    • CocoaPods 1.12.0 或更高版本
  • 确保您的 Unity 项目满足以下要求:

    • 对于 iOS - 目标为 iOS 13 或更高版本
    • 对于 tvOS - 目标为 tvOS 13 或更高版本
    • 对于 Android - 目标 API 级别为 21 (Lollipop) 或更高版本
  • 设置设备或使用模拟器运行 Unity 项目。

    • 对于 iOS 或 tvOS - 设置实体设备以运行您的应用,并完成以下任务:

      • 获取您的 Apple 开发者账号的 Apple 推送通知身份验证密钥。
      • 在 Xcode 中通过 App(应用)> Capabilities(功能)启用推送通知功能。
    • 对于 Android - 模拟器必须使用包含 Google Play 的模拟器映像。

如果您还没有 Unity 项目,只是想试用某一 Firebase 产品,可以下载我们的快速入门示例

第 1 步:创建 Firebase 项目

您必须创建一个 Firebase 项目以关联到 Unity 项目,然后才能将 Firebase 添加到该 Unity 项目。请访问了解 Firebase 项目以了解详情。

第 2 步:在 Firebase 中注册您的应用

您可以注册一个或多个应用或游戏,以便将其与 Firebase 项目关联。

  1. 前往 Firebase 控制台

  2. 在项目概览页面的中心位置,点击 Unity 图标 () 以启动设置工作流。

    如果您已向 Firebase 项目添加了应用,请点击添加应用以显示平台选项。

  3. 选择您要注册的 Unity 项目的 build 目标,甚至可以选择同时注册两个目标。

  4. 输入 Unity 项目针对具体平台的 ID。

    • 对于 iOS - 在 iOS 软件包 ID 字段中输入您的 Unity 项目的 iOS ID。

    • 对于 Android - 在 Android 软件包名称字段中输入您的 Unity 项目的 Android ID。
      “软件包名称”和“应用 ID”这两个术语通常可互换使用。

  5. (可选)输入 Unity 项目针对具体平台的别名。
    这些别名是方便内部使用的标识符,只有您能在 Firebase 控制台中看到。

  6. 点击注册应用

第 3 步:添加 Firebase 配置文件

  1. Firebase 控制台设置工作流中,获取针对具体平台的 Firebase 配置文件。

    • 对于 iOS - 点击下载 GoogleService-Info.plist

    • 对于 Android - 点击下载 google-services.json

  2. 打开 Unity 项目的 Project(项目)窗口,然后将您的配置文件移到 Assets 文件夹中。

  3. 返回 Firebase 控制台,在设置工作流中,点击下一步

第 4 步:添加 Firebase Unity SDK

  1. Firebase 控制台中,点击下载 Firebase Unity SDK,然后将此 SDK 解压缩到方便的位置。

    • 您可以随时再次下载 Firebase Unity SDK

    • Firebase Unity SDK 不局限于特定平台。

  2. 在您打开的 Unity 项目中,依次转到 Assets > Import Package > Custom Package

  3. 从解压缩的 SDK 中,选择您希望在应用中使用且受支持的 Firebase 产品

    为了获得最佳的 Firebase Cloud Messaging 使用体验,我们建议您在项目中启用 Google Analytics。此外,在设置 Analytics 时,您还需要将适用于 Analytics 的 Firebase 软件包添加到您的应用中。

    已启用 Analytics

    • 添加适用于 Google Analytics 的 Firebase 软件包:FirebaseAnalytics.unitypackage
    • 添加适用于 Firebase Cloud Messaging 的软件包:FirebaseMessaging.unitypackage

    未启用 Analytics

    添加适用于 Firebase Cloud Messaging 的软件包:FirebaseMessaging.unitypackage

  4. 在“Import Unity Package”窗口中,点击 Import

  5. 返回 Firebase 控制台,在设置工作流中,点击下一步

第 5 步:确认 Google Play 服务版本要求

Android 版 Firebase Unity SDK 需要使用 Google Play services。您必须先将 Google Play 服务更新为最新版本,然后才能使用该 SDK。

在应用的开头添加以下 using 语句和初始化代码。在调用 SDK 中的任何其他方法之前,您可在此代码段中检查 Google Play services 版本是否符合 Firebase Unity SDK 的要求,并视情况将其更新为相应版本。

using Firebase.Extensions;
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
  var dependencyStatus = task.Result;
  if (dependencyStatus == Firebase.DependencyStatus.Available) {
    // Create and hold a reference to your FirebaseApp,
    // where app is a Firebase.FirebaseApp property of your application class.
       app = Firebase.FirebaseApp.DefaultInstance;

    // Set a flag here to indicate whether Firebase is ready to use by your app.
  } else {
    UnityEngine.Debug.LogError(System.String.Format(
      "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
    // Firebase Unity SDK is not safe to use here.
  }
});

您的 Unity 项目已注册,并配置为使用 Firebase。

上传您的 APNs 身份验证密钥以获取 Apple 支持

将您的 APNs 身份验证密钥上传到 Firebase。如果您还没有 APNs 身份验证密钥,请务必在 Apple Developer Member Center 内创建一个。

  1. Firebase 控制台中,在您的项目内依次选择齿轮图标 > 项目设置 > Cloud Messaging 标签页。

  2. iOS 应用配置下的 APNs 身份验证密钥中,点击上传按钮。

  3. 转到您保存密钥的位置,选择该密钥,然后点击打开。添加该密钥的 ID(可在 Apple Developer Member Center 中找到),然后点击上传

在 Apple 平台上启用推送通知

第 1 步:添加用户通知框架

  1. 点击 Xcode 中的项目,然后从 Editor area(编辑区)中选择 General(通用)标签页。

  2. 向下滚动到 Linked Frameworks and Libraries(关联的框架和库),然后点击 + 号按钮以添加框架。

  3. 在出现的窗口中,滚动到 UserNotifications.framework,点击该条目,然后点击 Add(添加)。

第 2 步:启用推送通知

  1. 点击 Xcode 中的项目,然后从 Editor area(编辑区)中选择 Capabilities(功能)标签页。

  2. Push Notifications(推送通知)切换为 On(启用)。

  3. 向下滚动到 Background Modes(后台模式),然后将其切换为 On(启用)。

  4. Background Modes(后台模式)下选择 Remote notifications(远程通知)复选框。

初始化 Firebase Cloud Messaging

当为 TokenReceivedMessageReceived 事件添加处理程序时,Firebase Cloud Messaging 库将会初始化。

在初始化时,将为客户端应用实例请求一个注册令牌。应用将通过 OnTokenReceived 事件接收令牌,并应缓存该令牌以备以后使用。如果您希望针对此特定设备发送消息,则需要使用此令牌。

此外,如果您希望能够接收传入的消息,则需要注册 OnMessageReceived 事件。

整个设置过程如下所示:

public void Start() {
  Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
  Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token) {
  UnityEngine.Debug.Log("Received Registration Token: " + token.Token);
}

public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e) {
  UnityEngine.Debug.Log("Received a new message from: " + e.Message.From);
}

配置 Android 入口点 Activity

在 Android 上,Firebase Cloud Messaging 附带了自定义入口点 activity,用以替换默认的 UnityPlayerActivity。如果您使用的不是自定义入口点,则系统会自动进行此替换,无需您执行任何其他操作。不使用默认入口点 Activity 或提供自己的 Assets/Plugins/AndroidManifest.xml 的应用将需要额外的配置。

Android 上的 Firebase Cloud Messaging Unity 插件打包了两个附加文件:

  • Assets/Plugins/Android/libmessaging_unity_player_activity.jar 包含一个名为 MessagingUnityPlayerActivity 的 Activity,该 Activity 会替代标准 UnityPlayerActivity
  • Assets/Plugins/Android/AndroidManifest.xml 会指示应用使用 MessagingUnityPlayerActivity 作为应用的入口点。

提供这些文件是因为默认的 UnityPlayerActivity 不处理 onStoponRestart activity 生命周期转换或者实现 onNewIntent,而后者对于 Firebase Cloud Messaging 正确处理传入消息是必需的。

配置自定义入口点 Activity

如果您的应用没有使用默认的 UnityPlayerActivity,则您需要移除提供的 AndroidManifest.xml,并确保您的自定义 Activity 可正确处理 Android Activity 生命周期的所有转换(具体操作方法如下例所示)。如果您的自定义 Activity 扩展了UnityPlayerActivity,您可以改为扩展 com.google.firebase.MessagingUnityPlayerActivity,该类中实现了所有必要的方法。

如果您使用自定义 Activity 且未扩展 com.google.firebase.MessagingUnityPlayerActivity,则应在您的 Activity 中添加以下代码段:

/**
 * Workaround for when a message is sent containing both a Data and Notification payload.
 *
 * When the app is in the background, if a message with both a data and notification payload is
 * received the data payload is stored on the Intent passed to onNewIntent. By default, that
 * intent does not get set as the Intent that started the app, so when the app comes back online
 * it doesn't see a new FCM message to respond to. As a workaround, we override onNewIntent so
 * that it sends the intent to the MessageForwardingService which forwards the message to the
 * FirebaseMessagingService which in turn sends the message to the application.
 */
@Override
protected void onNewIntent(Intent intent) {
  Intent message = new Intent(this, MessageForwardingService.class);
  message.setAction(MessageForwardingService.ACTION_REMOTE_INTENT);
  message.putExtras(intent);
  message.setData(intent.getData());
  // For older versions of Firebase C++ SDK (< 7.1.0), use `startService`.
  // startService(message);
  MessageForwardingService.enqueueWork(this, message);
}

/**
 * Dispose of the mUnityPlayer when restarting the app.
 *
 * This ensures that when the app starts up again it does not start with stale data.
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
  if (mUnityPlayer != null) {
    mUnityPlayer.quit();
    mUnityPlayer = null;
  }
  super.onCreate(savedInstanceState);
}

新版本的 Firebase C++ SDK(7.1.0 及更高版本)使用 JobIntentService,这需要在 AndroidManifest.xml 文件中进行额外修改。

<service android:name="com.google.firebase.messaging.MessageForwardingService"
     android:permission="android.permission.BIND_JOB_SERVICE"
     android:exported="false" >
</service>

关于 Android 上的消息传递的注意事项

当应用没有运行而用户点按通知时,默认情况下消息不会通过 FCM 的内置回调进行传递。在这种情况下,消息载荷是通过用于启动应用的 Intent 接收的。

当应用在后台时,用户设备接收到的消息会将其通知字段的内容用于填充系统任务栏通知,但该通知内容并不会传输给 FCM。也就是说,FirebaseMessage.Notification 将为空。

总结:

应用状态 通知 数据 两者
前台 Firebase.Messaging.FirebaseMessaging.MessageReceived Firebase.Messaging.FirebaseMessaging.MessageReceived Firebase.Messaging.FirebaseMessaging.MessageReceived
背景 系统任务栏 Firebase.Messaging.FirebaseMessaging.MessageReceived 通知:系统任务栏
数据:intent 的 extras 属性。

防止自动初始化

FCM 会生成一个用于设备定位的注册令牌。生成令牌时,库会将标识符和配置数据上传到 Firebase。如果您希望在使用令牌之前能够明确地自行选择,则可以通过在配置时停用 FCM(如果是 Android,则还要停用 Analytics)来防止生成该令牌。如需执行此操作,请向 Apple 上的 Info.plist(不是 GoogleService-Info.plist)或 Android 上的 AndroidManifest.xml 添加一个元数据值:

Android

<?xml version="1.0" encoding="utf-8"?>
<application>
  <meta-data android:name="firebase_messaging_auto_init_enabled"
             android:value="false" />
  <meta-data android:name="firebase_analytics_collection_enabled"
             android:value="false" />
</application>

Swift

FirebaseMessagingAutoInitEnabled = NO

如需重新启用 FCM,您可以执行运行时调用:

Firebase.Messaging.FirebaseMessaging.TokenRegistrationOnInitEnabled = true;

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

FCM 允许将包含深层链接的消息发送到您的应用中。如需接收包含深层链接的消息,您必须在为应用处理深层链接的 Activity 中添加一个新的 intent 过滤器,该 intent 过滤器应能捕获您的网域的深层链接。如果您的消息不包含深层链接,则不需要此配置。在 AndroidManifest.xml 中:

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="http"/>
  <data android:host="CHANGE_THIS_DOMAIN.example.com" android:scheme="https"/>
</intent-filter>

您也可以指定通配符以使 intent 过滤器更加灵活。例如:

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:host="*.example.com" android:scheme="http"/>
  <data android:host="*.example.com" android:scheme="https"/>
</intent-filter>

当用户点按的通知包含指向您指定的架构和主机的链接时,您的应用将会启动含此 intent 过滤器的 Activity 来处理该链接。

后续步骤

设置客户端应用后,即可使用 Firebase 发送下行消息和主题消息。如需了解详情,请参阅对此功能进行了演示的快速入门示例

如需向您的应用添加其他更高级的行为,请参阅从应用服务器发送消息的指南:

请注意,您需要完成服务器实现才能利用这些功能。