在 JavaScript 用戶端中接收訊息

訊息的行為會因網頁處於前景 (有焦點)、背景、隱藏在其他分頁後方或完全關閉而有所不同。無論如何,網頁都必須處理 onMessage 回呼,但在背景情況下,您可能還需要處理 onBackgroundMessage 或設定顯示通知,讓使用者將您的網路應用程式帶到前景。

應用程式狀態 通知 資料 兩者並用
前景 onMessage onMessage onMessage
背景 (Service Worker) onBackgroundMessage (自動顯示通知) onBackgroundMessage onBackgroundMessage (自動顯示通知)

JavaScript 快速入門範例會示範接收訊息所需的所有程式碼。

在前景處理網頁應用程式訊息

如要接收 onMessage 事件,應用程式必須在 firebase-messaging-sw.js 中定義 Firebase 訊息服務 worker。或者,您也可以透過 getToken(): Promise<string>,將現有的服務工作者提供給 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.
// Replace 10.13.2 with latest version of the Firebase JS SDK.
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.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);
  // ...
});

在網頁應用程式於背景執行時處理訊息

應用程式在背景執行時收到的所有訊息,都會觸發瀏覽器顯示通知。您可以透過應用程式伺服器的傳送要求,或在用戶端使用服務工作者邏輯,為這項通知指定選項,例如標題或點擊動作。

在傳送要求中設定通知選項

針對從應用程式伺服器傳送的通知訊息,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,建議您在所有資料訊息中加入通知酬載。或者,您也可以使用服務工作者處理通知。

如要瞭解通知和資料訊息之間的差異,請參閱「訊息類型」。

在服務工作者中設定通知選項

針對資料訊息,您可以在服務工作者中設定通知選項。首先,請在服務工作站中初始化應用程式:

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.
// Replace 10.13.2 with latest version of the Firebase JS SDK.
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.13.2/firebase-messaging-compat.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.js 中呼叫 onBackgroundMessage。在本範例中,我們會建立包含標題、內文和圖示欄位的通知。

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 for Web 傳送通知的開發人員而言,最重要的考量因素是精確度和相關性。以下是確保通知精確且相關的具體建議:

  • 使用圖示欄位傳送有意義的圖片。在許多用途中,這應該是使用者能立即辨識的公司或應用程式標誌。或者,在聊天應用程式中,這可能會是傳送者的個人資料圖片。
  • 使用標題欄位說明訊息的確切性質。舉例來說,「Jimmy 回覆了」比「新訊息」更能傳達準確的資訊。請勿將這個寶貴的空間用於公司或應用程式名稱,請使用圖示來顯示這類資訊。
  • 請勿使用通知標題或內文顯示網站名稱或網域,因為通知中已包含網域名稱。
  • 新增 fcm_options.link,通常用於將使用者連結回網頁應用程式,並在瀏覽器中將焦點移至該應用程式。在極少數情況下,如果您需要傳達的所有資訊都能納入通知,則可能不需要連結。