You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在PWA中使用Firebase实现点击推送通知打开指定页面

问题描述

我已在PWA中成功集成Firebase,能够在应用处于后台或关闭状态时接收推送通知。但点击推送通知时,应用始终打开manifest.json文件中配置的start_url页面。我希望实现点击通知时打开PWA中的指定页面,尝试使用click_action参数:

{
    "notification":{
        "click_action": "/my-page"
    },
  "data":{
    "title":"Test",
    "message":"test"
  }, "to":"TOKEN"
}

也尝试过fcm_options.link参数:

{
    "webpush": {
      "fcm_options": {
        "link": "https://my.app/my-page"
      }
    },
  "data":{
    "title":"Test",
    "message":"test"
  }, "to":"TOKEN"
}

两种方式均被忽略,应用仍打开start_url。以下是我的firebase-messaging-sw.js代码:

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


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

messaging.onBackgroundMessage((payload) => {
  console.log(
    '[firebase-messaging-sw.js] Received background message ',
    payload
  );
  // Customize notification here
  const notificationTitle = payload.data.title;
  const notificationOptions = {
    body: payload.data.message,
  };

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

请问如何实现点击推送通知打开指定页面?是否可以在notificationOptions中添加点击操作?

解决方案

问题出在你手动调用了self.registration.showNotification,这会覆盖Firebase默认的通知处理逻辑,包括click_action和fcm_options.link的跳转行为。要实现点击通知打开指定页面,有两种可行方式:

方式一:利用Firebase默认通知处理(不自定义showNotification)

如果你的通知内容不需要高度自定义,可以移除messaging.onBackgroundMessage的自定义逻辑,让Firebase自动处理通知展示。此时你发送的click_action或fcm_options.link参数会生效:

  • 若使用click_action,确保参数值是相对路径(如/my-page),且你的PWA已正确配置路由;
  • 若使用fcm_options.link,需传入完整的绝对URL(如https://my.app/my-page)。

方式二:自定义通知点击事件(保留showNotification)

如果必须通过onBackgroundMessage自定义通知内容,需要手动监听通知的点击事件,并在事件中指定跳转页面。修改你的firebase-messaging-sw.js代码如下:

// 原有的初始化代码不变...

messaging.onBackgroundMessage((payload) => {
  console.log('[firebase-messaging-sw.js] Received background message ', payload);
  
  // 从payload中获取目标页面地址,可根据实际传递的参数调整
  const targetUrl = payload.notification?.click_action || payload.webpush?.fcm_options?.link || '/';
  
  const notificationTitle = payload.data.title;
  const notificationOptions = {
    body: payload.data.message,
    // 将目标地址存入通知的data字段,供点击事件读取
    data: { url: targetUrl }
  };

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

// 监听通知点击事件
self.addEventListener('notificationclick', (event) => {
  event.notification.close(); // 关闭通知
  
  const targetUrl = event.notification.data.url;
  
  // 打开指定页面:若页面已存在则聚焦,否则新建标签页
  event.waitUntil(
    clients.matchAll({ type: 'window', includeUncontrolled: true })
      .then((clientList) => {
        // 检查是否已有打开的目标页面
        for (const client of clientList) {
          if (client.url.includes(targetUrl) && 'focus' in client) {
            return client.focus();
          }
        }
        // 没有则打开新页面
        if (clients.openWindow) {
          return clients.openWindow(targetUrl);
        }
      })
  );
});

注意事项

  • 确保目标页面在PWA的scope范围内,否则无法直接跳转;
  • 若使用自定义data字段传递目标地址,发送推送时需在data中添加对应字段(如"data": {"url": "/my-page"}),然后在代码中读取payload.data.url;
  • 测试时需确保service worker已更新,避免缓存旧代码导致不生效。

内容的提问来源于stack exchange,提问作者O'Niel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:57:42