C++ を使用して Firebase Cloud Messaging クライアント アプリを設定する

Firebase Cloud Messagingクライアントアプリに C++ で書き込みを行うには、Firebase Cloud Messaging API を使用します。Android と Apple プラットフォームそれぞれに必要な設定を追加すれば、両方のプラットフォームで C++ SDK を機能させることができます。

Firebase と FCM SDK を設定する

Android

  1. まだ追加していない場合は、Firebase を C++ プロジェクトに追加します

    • このリンク先のセットアップ手順では、Firebase C++ SDK を使用する場合のデバイスとアプリの要件(CMake を使用してアプリをビルドする場合の推奨事項など)を確認してください。

    • プロジェクト レベルの build.gradle ファイルの buildscript セクションと allprojects セクションの両方に Google の Maven リポジトリを組み込みます。

  2. JNI 環境とアクティビティを引数で渡し、Firebase App オブジェクトを作成します。

    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.frameworkfirebase_messaging.frameworkFirebase C++ SDK から Xcode プロジェクトにドラッグします。
  2. APNs 認証キーを Firebase にアップロードします。まだ APNs 認証キーを用意していない場合は、Apple Developer Member Center で作成してください。

    1. Firebase コンソールのプロジェクト内で歯車アイコンを選択し、[プロジェクトの設定]、[Cloud Messaging] タブの順に選択します。

    2. [iOS アプリの構成] の下の [APNs 認証キー] で [アップロード] ボタンをクリックします。

    3. キーを保存した場所に移動し、キーを選択して [開く] をクリックします。キーのキー ID(Apple Developer Member Center で確認できます)を追加し、[アップロード] をクリックします。

  3. プッシュ通知を有効にするように、Xcode プロジェクトを構成します。

    1. ナビゲータ領域からプロジェクトを選択します。
    2. エディタ領域からプロジェクト ターゲットを選択します。
    3. エディタ領域から [General] タブを選択します。

      1. [Linked Frameworks and Libraries] までスクロールし、[+] ボタンをクリックしてフレームワークを追加します。
      2. 表示されたウィンドウで、[UserNotifications.framework] までスクロールし、その項目をクリックして [Add] をクリックします。

        このフレームワークは、Xcode v8 以降でのみ表示され、このライブラリで必須となっています。

    4. エディタ領域から [Capabilities] タブを選択します。

      1. [Push Notifications] を [On] に切り替えます。
      2. [Background Modes] までスクロールして、[On] に切り替えます。
      3. [Background Modes] で [Remote notifications] を選択します。
  4. Firebase アプリ オブジェクトを作成します。

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

  5. firebase::messaging::Listener インターフェースを実装するクラスを定義します。

  6. アプリと構築済みリスナーを引数で渡し、Firebase Cloud Messaging を初期化します。

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

デバイス登録トークンにアクセスする

Firebase Cloud Messaging ライブラリの初期化の際に、クライアント アプリのインスタンス用に登録トークンがリクエストされます。アプリは OnTokenReceived コールバックで登録トークンを受け取ります。このトークンは firebase::messaging::Listener を実装するクラスで定義される必要があります。

その特定のデバイスをターゲットにする場合は、このトークンにアクセスする必要があります。

Android でのメッセージ配信に関する注意点

アプリがまったく実行されていないときにユーザーが通知をタップすると、デフォルトでは、メッセージが FCM の組み込みコールバックでルーティングされません。この場合、メッセージ ペイロードは、アプリの起動に使用される Intent を通じて受信されます。 FCM がこれらの受信メッセージを C++ ライブラリのコールバックに転送するようにするには、Activity の onNewIntent メソッドをオーバーライドし、IntentMessageForwardingService に渡す必要があります。

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 が null になります。

まとめると、次のとおりです。

アプリの状態 通知 データ 両方
フォアグラウンド OnMessageReceived OnMessageReceived OnMessageReceived
背景 システムトレイ OnMessageReceived 通知: システムトレイ
データ: インテントの追加部分内

Android でのカスタム メッセージ処理

アプリに送信される通知はデフォルトで ::firebase::messaging::Listener::OnMessageReceived に渡されますが、場合によってはデフォルトの動作をオーバーライドすることもできます。Android でこれを行うには、com.google.firebase.messaging.cpp.ListenerService を拡張するカスタムクラスを作成し、プロジェクトの AndroidManifest.xml を更新する必要があります。

ListenerService メソッドをオーバーライドします。

ListenerService は、アプリに送信された受信メッセージを傍受し、C++ ライブラリにルーティングする Java クラスです。アプリがフォアグラウンドにあるとき(またはアプリがバックグラウンドで、データのみのペイロードを受け取るとき)、メッセージはこのクラスで提供されるコールバックの 1 つを通過します。メッセージ処理にカスタム動作を追加するには、ListenerService のデフォルトの FCM を拡張する必要があります。

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 アーカイブには、FCM のデフォルトの AndroidManifest.xml を宣言する 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 ではアナリティクス)を無効にして生成を禁止できます。この操作を 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::SetTokenRegistrationOnInitEnabled(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>

指定したスキームとホストへのリンクを含む通知がタップされると、アプリがこのインテント フィルタを含むアクティビティを開始し、リンクを処理します。

次のステップ

クライアント アプリを設定したら、Firebase でダウンストリーム メッセージやトピック メッセージを送信できる状態になります。詳細については、ダウンロードして実行可能なクイックスタート サンプルでこの機能に関するデモをご確認ください。

別のより高度な動作をアプリに追加するには、アプリサーバーからのメッセージの送信に関するガイドをご覧ください。

これらの機能を利用するには、サーバーの実装が必要です。