Android で Firebase Cloud Messaging クライアント アプリを設定する

FCM クライアントには Android 4.4 以降を搭載しているデバイスが必要です。またそのデバイスには、Google Play ストア アプリがインストールされているか、Google API を使用して Android 4.4 が動作しているエミュレータが搭載されている必要があります。ただし、開発した Android アプリは Google Play ストア経由以外の手段でもデプロイできます。

SDK を設定する

他の Firebase 機能をアプリですでに有効にしている場合、このセクションで説明しているタスクはすでに完了している可能性があります。タスクを完了していない場合は、Android プロジェクトに Firebase を追加します。

アプリ マニフェストを編集する

アプリのマニフェストに次の追加を行います。

  • 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 を使用して、この権限のランタイム バージョンをリクエストする必要があります。ユーザーがこの権限を付与するまで、アプリは通知を表示できません。

新しいランタイム権限をリクエストするには:

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() {
    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);
    }
}

Kotlin+KTX

// 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() {
    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)
    }
}

通常は、通知を表示する権限をアプリに付与した場合に有効になる機能についてユーザーに説明する UI を表示する必要があります。この UI では、同意または拒否のユーザー オプション([OK] ボタンや [いいえ] ボタンなど)を提供する必要があります。ユーザーが [OK] を選択した場合は、直接権限をリクエストします。ユーザーが [いいえ] を選択した場合は、通知なしで使用を継続できるようにします。

アプリがユーザーに POST_NOTIFICATIONS 権限をリクエストする際のベスト プラクティスについては、通知のランタイム権限をご覧ください。

Android 12L(API レベル 32)以下をターゲットとするアプリの通知権限

アプリがフォアグラウンドにある場合、アプリが初めて通知チャンネルを作成するときに、Android は自動的にユーザーに権限を求めます。ただし、チャンネルの作成と権限のリクエストのタイミングについては、次の点に注意してください。

  • アプリがバックグラウンドで動作しているときに最初の通知チャンネルを作成する場合(これは FCM SDK が FCM 通知を受信したときの動作です)、Android は通知の表示を許可せず、アプリが次に開かれるまで通知権限をユーザーに求めません。つまり、アプリが開かれてユーザーが権限を承認する前に受信した通知はすべて失われます
  • プラットフォームの API を利用して権限をリクエストするには、Android 13 以降をターゲットとするようにアプリを更新することを強くおすすめします。それができない場合は、アプリは通知がアプリに送信される前に通知チャンネルを作成して通知権限ダイアログをトリガーし、通知が失われないようにする必要があります。詳細については、通知権限に関するベスト プラクティスをご覧ください。

オプション: 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() を呼び出します。

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();
        }
    });

Kotlin+KTX

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()
})

トークンの生成をモニタリングする

onNewToken コールバックは、新しいトークンが生成されるたびに呼び出されます。

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);
}

Kotlin+KTX

/**
 * 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)
}

トークンの取得後は、それをアプリサーバーに送信し、適切な方法で保管できます。

Google Play 開発者サービスをチェックする

Play 開発者サービスの SDK に依存するアプリについては、Google Play 開発者サービス機能にアクセスする前に、互換性のある Google Play 開発者サービスの APK がデバイスにインストールされているかどうかをアプリが必ずチェックする必要があります。このチェックは、メイン アクティビティの onCreate() メソッドと onResume() メソッドの 2 か所で行うことをおすすめします。onCreate() では、チェックにパスしないとアプリを使用できないようにします。onResume() では、ユーザーが [戻る] ボタンなどの他の手段を使って実行中のアプリに戻った場合にもチェックされるようにします。

互換性のあるバージョンの Google Play 開発者サービスがデバイスにインストールされていない場合は、アプリで GoogleApiAvailability.makeGooglePlayServicesAvailable() を呼び出すと、ユーザーが Google Play ストアから Google Play 開発者サービスをダウンロードできるようになります。

自動初期化を禁止する

FCM 登録トークンが生成されると、ライブラリでは、その ID と構成データが Firebase にアップロードされます。トークンの自動生成を禁止するには、次のようにメタデータ値を AndroidManifest.xml に追加して、アナリティクスの収集と 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 の自動初期化を再度有効にするには、ランタイム コールを実行します。

Java

FirebaseMessaging.getInstance().setAutoInitEnabled(true);

Kotlin+KTX

Firebase.messaging.isAutoInitEnabled = true

アナリティクスの収集を再度有効にするには、FirebaseAnalytics クラスの setAnalyticsCollectionEnabled() メソッドを呼び出します。次に例を示します。

setAnalyticsCollectionEnabled(true);

これらの値をいったん設定すると、アプリを再起動しても維持されます。

次のステップ

クライアント アプリの設定が完了すると、Notifications Composer でダウンストリーム メッセージを送信できるようになります。この機能は、ダウンロードして実行可能なクイックスタート サンプルで確認できます。

その他のより高度な動作をアプリに追加するには、インテント フィルタを宣言して、受信メッセージに応答するアクティビティを実装します。詳細については、アプリサーバーからメッセージを送信するためのガイドをご覧ください。

これらの機能を利用するには、サーバーの実装とサーバー プロトコル(HTTP または XMPP)、あるいは Admin SDK の実装が必要になることに注意してください。