使用 Firebase 雲端通訊接收訊息

本指南說明如何在行動和網頁用戶端應用程式中設定 Firebase Cloud Messaging,以便穩定接收訊息。

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

應用程式狀態 通知 資料 兩者並用
前景 onMessage onMessage onMessage
背景 (服務工作人員) onBackgroundMessage (自動顯示通知) onBackgroundMessage onBackgroundMessage (自動顯示通知)

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

在網頁應用程式於前景運作時處理訊息

如要接收 onMessage 事件,應用程式必須在 firebase-messaging-sw.js 中定義 Firebase 訊息服務工作人員。或者,您也可以透過 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.
// 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);
  // ...
});

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

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

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

如果是從應用程式伺服器傳送的通知訊息,FCMJavaScript 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": {
        ,
        "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 中初始化應用程式:

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,通常是為了將使用者帶回網頁應用程式,並在瀏覽器中將其設為焦點。在極少數情況下,如果通知可以完整傳達所有必要資訊,您可能就不需要連結。