複数の端末にメッセージを送信する

Firebase Cloud Messaging では、次の 2 つの方法で複数の端末を対象にメッセージングを行うことができます。

このチュートリアルは、FCM 用に HTTP または XMPP プロトコルを使ってアプリサーバーからトピック メッセージを送信する方法、およびウェブアプリでのそれらのメッセージを受信して処理する方法に重点を置いています。バックグラウンドとフォアグラウンドの両方のアプリについて、メッセージ処理を説明します。

SDK を設定する

FCM 用の JavaScript クライアント アプリの設定や、メッセージを受信する手順をすでに行っている場合は、このセクションに記載されている手順を完了している可能性があります。

Firebase を JavaScript プロジェクトに追加する

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

メッセージを受信するようにブラウザを設定する

ハードコード値 gcm_sender_id を指定するウェブアプリ マニフェストを追加する必要があります。このハードコード値は、FCM がこのアプリに対するメッセージ送信を許可されていることを示します。すでにアプリに manifest.json 設定ファイルが存在する場合は、次に示す正確なブラウザ送信者 ID を追加してください(値を変更しないでください)。

{
  "//": "Some browsers will use this to enable push notifications.",
  "//": "It is the same for all projects, this is not your project's sender ID",
  "gcm_sender_id": "103953800507"
}

メッセージング オブジェクトの取得

// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();

通知を受信する権限を要求する

メソッド messaging.requestPermission() は、ブラウザでアプリが通知を受け取れるようにするかどうか、ユーザーに許可を求める同意ダイアログを表示します。権限が拒否された場合は、FCM 登録トークン リクエストがエラーになります。

messaging.requestPermission()
.then(function() {
  console.log('Notification permission granted.');
  // TODO(developer): Retrieve an Instance ID token for use with FCM.
  // ...
})
.catch(function(err) {
  console.log('Unable to get permission to notify.', err);
});

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

このセクションでは、アプリ インスタンス用の登録トークンを取得する方法と、トークン更新イベントをモニタリングする方法について説明します。トークンは初期起動後にローテーションされている可能性があるため、トークン更新をモニタリングして、更新された最新の登録トークンを常に取得する必要があります。

登録トークンは次のような場合に変更されることがあります。

  • ウェブアプリが登録トークンを削除した場合。
  • ユーザーがブラウザデータをクリアした場合。この場合、新しいトークンを取得するには getToken を呼び出します。

現在の登録トークンの取得

現在のトークンを取得する必要がある場合は、getToken を呼び出します。まだ権限が付与されていない場合、このメソッドは null を返します。そうでない場合は、トークンを返すか、エラーが原因で Promise を拒否します。

  // Get Instance ID token. Initially this makes a network call, once retrieved
  // subsequent calls to getToken will return from cache.
  messaging.getToken()
  .then(function(currentToken) {
    if (currentToken) {
      sendTokenToServer(currentToken);
      updateUIForPushEnabled(currentToken);
    } else {
      // Show permission request.
      console.log('No Instance ID token available. Request permission to generate one.');
      // Show permission UI.
      updateUIForPushPermissionRequired();
      setTokenSentToServer(false);
    }
  })
  .catch(function(err) {
    console.log('An error occurred while retrieving token. ', err);
    showToken('Error retrieving Instance ID token. ', err);
    setTokenSentToServer(false);
  });
}

トークン更新のモニタリング

新しいトークンが生成されるたびに onTokenRefresh コールバックが呼び出されるため、そのコンテキストで getToken を呼び出すと、利用可能な最新の登録トークンに確実にアクセスできます。

// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(function() {
  messaging.getToken()
  .then(function(refreshedToken) {
    console.log('Token refreshed.');
    // Indicate that the new Instance ID token has not yet been sent to the
    // app server.
    setTokenSentToServer(false);
    // Send Instance ID token to app server.
    sendTokenToServer(refreshedToken);
    // ...
  })
  .catch(function(err) {
    console.log('Unable to retrieve refreshed token ', err);
    showToken('Unable to retrieve refreshed token ', err);
  });
});

トークンを取得したら、それをアプリサーバーに送信して、適切な方法で保管します。Instance ID server API を使用して、サブスクリプションに関する情報を取得することができます。

クライアント アプリをトピックに登録する

登録トークンとトピック名がわかっていれば、Google Instance ID サーバー API を使用して、トピックにトークンを追加できます。このエンドポイントで Instance ID API を呼び出して、アプリ インスタンスの登録トークンとトピック名を指定します。

 https://iid.googleapis.com/iid/v1/<REGISTRATION_TOKEN>/rel/topics/<TOPIC_NAME>

たとえば、「movies」という名前のトピックにアプリ インスタンスを登録するには、次に示すように、許可ヘッダーにサーバー API キーを追加して POST リクエストをサーバーからエンドポイントに送信します。

https://iid.googleapis.com/iid/v1/nKctODamlM4:CKrh_PC8kIb7O...clJONHoA/rel/topics/movies
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

サーバーキーの機密性を維持するため、このタイプのリクエストをクライアントから送信しないでください。

リクエストが成功した場合は、HTTP 200 OK が返されます。エラー レスポンスの詳細と一括リクエストの送信方法については、アプリ インスタンス用の関係マップの作成をご覧ください。

トピック メッセージを受信して処理する

メッセージの動作は、ページがフォアグラウンドにある(フォーカスされている)か、またはページがバックグラウンドにあり、他のタブに隠されているか、完全に閉じられているかによって異なります。いずれの場合も、onMessage コールバックをページで処理する必要がありますが、バックグラウンドの場合は、ユーザーがウェブアプリをフォアグラウンドに戻せるようにする表示通知も設定する必要があります。

アプリの状態 通知 データ ペイロード 両方
フォアグラウンド onMessage onMessage onMessage
バックグラウンド(サービス ワーカー) 表示通知 表示通知と click_action リンク 表示通知と click_action リンク

ウェブアプリがフォアグラウンドの場合にメッセージを処理する

onMessage イベントを受信するには、アプリが firebase-messaging-sw.js で Firebase メッセージング サービス ワーカーを定義する必要があります。または、useServiceWorker を使って既存のサービス ワーカーを指定することもできます。

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

アプリがフォアグラウンドにある(ユーザーがウェブアプリを現在閲覧している)場合は、そのページでデータと通知ペイロードを直接受信できます。

// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a sevice worker
//   `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage(function(payload) {
  console.log("Message received. ", payload);
  // ...
});

ウェブアプリがバックグラウンドの場合にメッセージを処理する

アプリがバックグラウンドで動作中になんらかのメッセージを受信すると、ブラウザ内の表示通知がトリガーされます。この通知に関するオプション(タイトルやクリック アクションなど)は、アプリサーバーからの送信リクエスト、またはクライアント上のサービス ワーカー ロジックで指定できます。

送信リクエストでの通知オプションの設定

アプリサーバーから送信される通知メッセージの場合は、FCM JavaScript API が click_action キーをサポートします。通常、これはウェブアプリ内のページに設定されるため、ユーザーが通知をクリックすると、アプリがフォアグラウンドに移動します。

https://fcm.googleapis.com/fcm/send
Content-Type: application/json
Authorization: key=AIzaSyC...akjgSX0e4

{ "notification": {
    "title": "Background Message Title",
    "body": "Background message body",
    "click_action" : "https://dummypage.com"
  },

  "to" : "/topics/matchday"

}

データ メッセージは click_action をサポートしないため、すべてのデータ メッセージに通知ペイロードを追加することをお勧めします。または、サービス ワーカーを使用して通知を処理することもできます。

通知メッセージとデータ メッセージの違いの説明については、メッセージのタイプをご覧ください。

サービス ワーカーでの通知オプションの設定

通知メッセージとデータ メッセージの両方に関して、サービス ワーカーで通知オプションを設定できます。まず、サービス ワーカーでアプリを初期化します。

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
  'messagingSenderId': 'YOUR-SENDER-ID'
});

// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();

オプションを設定するには、firebase-messaging-sw.jssetBackgroundMessageHandler を呼び出します。この例では、タイトル、本文、アイコン、クリック アクション用のオプションを設定します。

messaging.setBackgroundMessageHandler(function(payload) {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  // Customize notification here
  const notificationTitle = 'Background Message Title';
  const notificationOptions = {
    body: 'Background Message body.',
    icon: '/firebase-logo.png'
  };

  return self.registration.showNotification(notificationTitle,
      notificationOptions);
});

ビルド送信リクエスト

サーバー側から Firebase Cloud Messaging トピックへのメッセージの送信する方法は、個々の端末やユーザー グループ宛てのメッセージを送信する場合とよく似ています。この場合、アプリサーバーは to キーに /topics/yourTopic などの値を設定します。デベロッパーは、以下の正規表現に一致する任意のトピック名を選択できます。"/topics/[a-zA-Z0-9-_.~%]+"

トピック HTTP POST リクエスト

単一のトピックに送信します。

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}

トピック HTTP レスポンス

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}

トピック XMPP メッセージ

単一のトピックに送信します。

<message id="">
  <gcm xmlns="google:mobile:data">
{
  "to" : /topics/foo-bar",
  "priority" : "high",
  "notification" : {
    "body" : "This is a Firebase Cloud Messaging Topic Message!",
    "title" : "FCM Message",
  }
}
  </gcm>
</message>

トピック XMPP レスポンス

//Success example:
{
  "message_id": "1023456"
}

//failure example:
{
  "error": "TopicsMessageRateExceeded"
}

フィードバックを送信...

ご不明な点がありましたら、Google のサポートページをご覧ください。