開始在 C++ 應用程式中使用 Firebase 雲端通訊

選取平台: iOS+ Android Web Flutter Unity C++


本指南說明如何在 C++ 用戶端應用程式中開始使用 Firebase Cloud Messaging,以便可靠地傳送訊息。

如要使用 C++ 編寫跨平台 Firebase Cloud Messaging 用戶端應用程式,請使用 Firebase Cloud Messaging API。C++ SDK 適用於 Android 和 Apple 平台,但每個平台都需要額外設定。如要進一步瞭解 iOS 和 Android 適用的 C++ SDK 如何與 FCM 搭配運作,請參閱「瞭解 Firebase for C++」。

設定 Firebase 和 FCM SDK

Android

  1. 如果尚未新增,請將 Firebase 新增至 C++ 專案。

    • 請參閱連結的設定操作說明,瞭解使用 Firebase C++ SDK 的裝置和應用程式需求條件,包括建議使用 CMake 建構應用程式。

    • 在專案層級 build.gradle 檔案中,請務必在 buildscript 和 allprojects 區段中加入 Google 的 Maven 存放區。

  2. 建立 Firebase 應用程式物件,並傳入 JNI 環境和 Activity:

    app = ::firebase::App::Create(::firebase::AppOptions(), jni_env, activity);

  3. 定義實作 firebase::messaging::Listener 介面的類別。

  4. 初始化 FCM,並傳遞應用程式和建構的接聽程式:

    ::firebase::messaging::Initialize(app, listener);

  5. 依賴 Google Play 服務 SDK 的應用程式,應先檢查裝置是否有相容的 Google Play 服務 APK,再存取功能。詳情請參閱「檢查 Google Play 服務 APK」。

iOS+

  1. 如果您尚未將 Firebase 新增至 C++ 專案,請先新增。接著,請按照下列步驟為 FCM 設定專案:
    1. 在專案的 Podfile 中,新增 FCM 依附元件:
      pod 'FirebaseMessaging'
    2. 從 Firebase C++ SDK,將 firebase.framework 和 firebase_messaging.framework 框架拖曳至 Xcode 專案。
  2. 將 APNs 驗證金鑰上傳至 Firebase。如果還沒有 APNs 驗證金鑰,請務必在 Apple Developer Member Center 建立。

    1. 在 Firebase 控制台中,依序前往「 Settings」(設定) >「General」(一般)。接著,按一下「Cloud Messaging」(雲端通訊) 分頁標籤。
    2. 在「iOS app configuration」(iOS 應用程式設定) 下方的「APNs authentication key」(APN 驗證金鑰) 中,按一下「Upload」(上傳),上傳開發驗證金鑰和/或正式版驗證金鑰。至少擇一提供。
    3. 瀏覽至金鑰儲存位置,選取金鑰,然後按一下「Open」(開啟)。新增金鑰的 ID (可在 Apple Developer Member Center 中取得),然後按一下「上傳」。
  3. 設定 Xcode 專案,啟用推播通知:

    1. 在導覽器區域中選取專案。
    2. 從「編輯器區域」選取專案目標。
    3. 在「編輯器區域」中選取「一般」分頁標籤。

      1. 捲動至「Linked Frameworks and Libraries」,然後點選「+」按鈕新增架構。
      2. 在顯示的視窗中,捲動至「UserNotifications.framework」,依序點選該項目和「Add」。

        這個架構只會顯示在 Xcode 第 8 版和後續版本中,且這個程式庫需要這個架構。

    4. 在「編輯器區域」中選取「功能」分頁標籤。

      1. 將「推播通知」切換為「開啟」。
      2. 捲動至「Background Modes」,然後切換為「On」。
      3. 在「Background Modes」下方,選取「Remote notifications」。
  4. 建立 Firebase 應用程式物件:

    app = ::firebase::App::Create(::firebase::AppOptions());

  5. 定義實作 firebase::messaging::Listener 介面的類別。

  6. 初始化 Firebase 雲端通訊,傳入應用程式和建構的事件監聽器:

    ::firebase::messaging::Initialize(app, listener);

存取 Firebase 安裝 ID

使用 Firebase 安裝 ID 啟用註冊

如要使用 Firebase 安裝 ID (FID) 啟用向 FCM 註冊應用程式例項的功能,請先在 Android 和 Apple 平台的應用程式設定中啟用 FID:

Android

在 AndroidManifest.xml 的 <application> 元素中加入下列 <meta-data> 元素:

<meta-data android:name="firebase_messaging_installation_id_enabled"
           android:value="true" />

Swift

將 FirebaseMessagingInstallationIdEnabled 鍵新增至 Info.plist,並設為 YES:

FirebaseMessagingInstallationIdEnabled = YES

實作 onRegistrationReceived 監聽器

初始化 Firebase Cloud Messaging 程式庫時,系統會註冊用戶端應用程式例項,以便使用 Firebase 安裝 ID (FID) 接收訊息。應用程式會透過 OnRegistrationReceived 回呼收到 FID,這個回呼應在 firebase::messaging::Listener 實作中定義:

class MyListener : public firebase::messaging::Listener {
 public:
  void OnRegistrationReceived(const char* installation_id) override {
    LogMessage("Received Firebase Installation ID: %s", installation_id);
    // TODO: Send the Firebase Installation ID (FID) to your app server to
    // target this device for messages.
  }
};

如要指定該特定應用程式執行個體,請將 FID 傳送至應用程式伺服器,並使用偏好的方法儲存。

停用自動初始化時,請手動註冊

您也可以在執行階段使用 FCM 透過 Register() 手動觸發註冊:

// Manually register with FCM
firebase::Future<void> register_future = firebase::messaging::Register();
register_future.OnCompletion([](const firebase::Future<void>& future) {
  if (future.status() == firebase::kFutureStatusComplete &&
      future.error() == 0) {
    // Note: The registered Firebase Installation ID is delivered to the
    // OnRegistrationReceived callback.
    LogMessage("Registered with FCM");
  }
});

存取 FCM 註冊權杖 (已淘汰)

初始化 Firebase Cloud Messaging 程式庫時,系統會要求用戶端應用程式執行個體提供註冊權杖。應用程式會透過 OnTokenReceived 回呼接收權杖,這個回呼應在實作 firebase::messaging::Listener 的類別中定義。

如要指定該特定應用程式執行個體,您必須取得這個權杖。

Android 裝置上的訊息傳送注意事項

如果應用程式完全未執行,且使用者輕觸通知,則根據預設,訊息不會透過 FCM 的內建回呼轉送。在這種情況下,系統會透過用於啟動應用程式的 Intent 接收訊息酬載。如要讓 FCM 將這些傳入訊息轉送至 C++ 程式庫回呼,您必須覆寫 Activity 中的 onNewIntent 方法,並將 Intent 傳遞至 MessageForwardingService。

import com.google.firebase.messaging.MessageForwardingService;

class MyActivity extends Activity {
  private static final String TAG = "MyActvity";

  @Override
  protected void onNewIntent(Intent intent) {
    Log.d(TAG, "A message was sent to this app while it was in the background.");
    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);
  }
}

應用程式在背景執行時收到的訊息,會使用通知欄位的內容填入系統匣通知,但該通知內容不會傳送至 FCM。也就是說,Message::notification 將為空值。

簡單來說:

應用程式狀態 通知 資料 兩者並用
前景 OnMessageReceived OnMessageReceived OnMessageReceived
背景 系統匣 OnMessageReceived 通知:系統匣
資料:意圖的額外資訊。

在 Android 上處理自訂訊息

根據預設,傳送至應用程式的通知會傳遞至 ::firebase::messaging::Listener::OnMessageReceived,但在某些情況下,您可能想覆寫預設行為。如要在 Android 上執行這項操作,您必須編寫擴充 com.google.firebase.messaging.cpp.ListenerService 的自訂類別,並更新專案的 AndroidManifest.xml。

覆寫 ListenerService 方法

ListenerService 是 Java 類別,可攔截傳送至應用程式的收到的訊息,並將訊息傳送至 C++ 程式庫。應用程式位於前景時 (或應用程式位於背景,且收到僅含資料的酬載時),訊息會透過這個類別提供的其中一個回呼傳遞。如要為訊息處理新增自訂行為,您必須擴充 FCM 的預設 ListenerService:

import com.google.firebase.messaging.cpp.ListenerService;

class MyListenerService extends ListenerService {

覆寫 ListenerService.onMessageReceived 方法後,您就能根據收到的 RemoteMessage 物件執行動作,並取得訊息資料:

@Override
public void onMessageReceived(RemoteMessage message) {
  Log.d(TAG, "A message has been received.");
  // Do additional logic...
  super.onMessageReceived(message);
}

ListenerService 還有其他幾種較少使用的方法。這些也可以覆寫,詳情請參閱 FirebaseMessagingService 參考資料。

@Override
public void onDeletedMessages() {
  Log.d(TAG, "Messages have been deleted on the server.");
  // Do additional logic...
  super.onDeletedMessages();
}

@Override
public void onMessageSent(String messageId) {
  Log.d(TAG, "An outgoing message has been sent.");
  // Do additional logic...
  super.onMessageSent(messageId);
}

@Override
public void onSendError(String messageId, Exception exception) {
  Log.d(TAG, "An outgoing message encountered an error.");
  // Do additional logic...
  super.onSendError(messageId, exception);
}

更新「AndroidManifest.xml」

編寫自訂類別後,必須將其納入 AndroidManifest.xml 才能生效。請在 <manifest> 標記中宣告適當的屬性,確保資訊清單包含合併工具,如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.firebase.messaging.cpp.samples"
    xmlns:tools="http://schemas.android.com/tools">

firebase_messaging_cpp.aar 封存檔中有一個 AndroidManifest.xml 檔案,用於宣告 FCM 的預設 ListenerService。這份資訊清單通常會與專案專屬資訊清單合併,ListenerService 才能執行。這個 ListenerService 必須替換為自訂監聽器服務。方法是移除預設的 ListenerService,並新增自訂服務,這可以透過專案 AndroidManifest.xml 檔案中的下列程式碼行完成:

<service android:name="com.google.firebase.messaging.cpp.ListenerService"
         tools:node="remove" />
<service android:name="com.google.firebase.messaging.cpp.samples.MyListenerService"
         android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT"/>
  </intent-filter>
</service>

新版 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>

防止自動初始化

FCM 會產生註冊權杖,用於指定應用程式執行個體。產生權杖時,程式庫會將 ID 和設定資料上傳至 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::SetRegistrationOnInitEnabled(true);

設定後,即使重新啟動應用程式,這個值仍會保留。

FCM 允許傳送包含應用程式深層連結的訊息。如要接收包含深層連結的訊息,您必須在處理應用程式深層連結的活動中,新增意圖篩選器。意圖篩選器應擷取網域的深層連結。如果訊息不含深層連結,就不必進行這項設定。在 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-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>

使用者輕觸的通知含有您指定配置和主機的連結時,應用程式會啟動含有這個意圖篩選器的活動,以便處理連結。

後續步驟

完成設定步驟後,您可以選擇下列幾種方式,繼續使用 C++ 版 FCM: