JavaScript クライアントでメッセージを受信する

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

アプリの状態 通知 データ 両方
フォアグラウンド onMessage onMessage onMessage
バックグラウンド(Service Worker) onBackgroundMessage(表示通知が自動的に表示されます) onBackgroundMessage onBackgroundMessage(表示通知が自動的に表示されます)

JavaScript クイックスタート サンプルには、メッセージの受信に必要なすべてのコードが示されています。

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

アプリが onMessage イベントを受信するには、firebase-messaging-sw.js で Firebase メッセージング Service Worker を定義する必要があります。あるいは、getToken(): Promise<string> を使用して既存の Service Worker を SDK に指定することもできます。

Web

import { initializeApp } from "firebase/app";
import { getMessaging } from "firebase/messaging/sw";

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
const firebaseApp = initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

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

Web

// 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/8.10.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

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

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

Web

// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a service worker
//   `messaging.onBackgroundMessage` handler.
import { getMessaging, onMessage } from "firebase/messaging";

const messaging = getMessaging();
onMessage(messaging, (payload) => {
  console.log('Message received. ', payload);
  // ...
});

Web

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

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

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

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

アプリサーバーから送信される通知メッセージの場合は、FCM JavaScript API が fcm_options.link キーに対応しています。通常、これはウェブアプリ内のページに設定されます。

https://fcm.googleapis.com//v1/projects/<YOUR-PROJECT-ID>/messages:send
Content-Type: application/json
Authorization: bearer <YOUR-ACCESS-TOKEN>

{
  "message": {
    "token": "eEz-Q2sG8nQ:APA91bHJQRT0JJ...",
    "notification": {
      "title": "Background Message Title",
      "body": "Background message body"
    },
    "webpush": {
      "fcm_options": {
        "link": "https://dummypage.com"
      }
    }
  }
}

リンク値が指しているページがすでにブラウザタブで開いている場合は、通知をクリックするとそのタブがフォアグラウンドに移動します。そのページがまだ開いていない場合は、通知をクリックするとそのページが新しいタブで開きます。

データ メッセージは fcm_options.link に対応していないため、すべてのデータ メッセージに通知ペイロードを追加することをおすすめします。または、Service Worker を使用して通知を処理することもできます。

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

Service Worker での通知オプションの設定

データ メッセージの場合、Service Worker で通知オプションを設定できます。まず、Service Worker でアプリを初期化します。

Web

import { initializeApp } from "firebase/app";
import { getMessaging } from "firebase/messaging/sw";

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
const firebaseApp = initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

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

Web

// 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/8.10.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-messaging.js');

// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
firebase.initializeApp({
  apiKey: 'api-key',
  authDomain: 'project-id.firebaseapp.com',
  databaseURL: 'https://project-id.firebaseio.com',
  projectId: 'project-id',
  storageBucket: 'project-id.appspot.com',
  messagingSenderId: 'sender-id',
  appId: 'app-id',
  measurementId: 'G-measurement-id',
});

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

オプションを設定するには、firebase-messaging-sw.jsonBackgroundMessage を呼び出します。この例では、title、body、icon の各フィールドを含む通知を作成します。

Web

import { getMessaging } from "firebase/messaging/sw";
import { onBackgroundMessage } from "firebase/messaging/sw";

const messaging = getMessaging();
onBackgroundMessage(messaging, (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'
  };

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

Web

messaging.onBackgroundMessage((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'
  };

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

通知のベスト プラクティス

ウェブのプッシュ メッセージングを十分に理解されている場合は、優れた通知を行うための広範なガイドラインをすでにお読みかもしれません。ウェブ用 FCM を通じて通知を送信するデベロッパーにとっては、精度と関連性が最も重要な考慮事項になります。通知の精度と関連性を保つための具体的な推奨事項を以下に示します。

  • 重要な画像を送信するには、アイコン フィールドを使用します。ほとんどの場合、そのような画像はユーザーがすぐに認識できるような会社またはアプリのロゴにする必要があります。または、チャット アプリケーションの場合は、送信側のユーザーのプロフィール画像などが考えられます。
  • タイトル フィールドを使用して、メッセージの正確な特性を表現します。たとえば、「田中さんが応答しました」というタイトルは、「新しいメッセージ」よりも正確な情報を伝えます。この貴重なスペースを会社やアプリの名前に使わないでください。そのような目的にはアイコンを使用してください。
  • 通知のタイトルまたは本文を使ってウェブサイトの名前またはドメインを表示しないでください。通知にはすでにドメイン名が含まれています。
  • 通常、fcm_options.link を追加することで、ユーザーをウェブアプリにリンクし、ブラウザにフォーカスを移します。伝える必要がある情報のすべてが通知に収まるようなまれなケースでは、リンクは必要ありません。