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

FCM更新后调用错误Service Worker导致消息接收故障求助

问题解决:FCM消息接收失效(多Service Worker冲突)

核心原因

你同时注册了两个作用域相同的Service Worker:firebase-messaging-sw.js和自定义的service-worker.js。部署更新后,自定义SW会取代FCM的SW成为激活状态的Worker,而FCM的推送消息只能被初始关联的SW接收,导致后续收不到消息。


方案1:合并两个Service Worker(推荐)

将FCM的消息处理逻辑整合到自定义SW中,彻底避免冲突。

  1. 修改自定义service-worker.js,加入FCM逻辑
// 导入Firebase Messaging模块
import { initializeApp } from "firebase/app";
import { getMessaging, onBackgroundMessage } from "firebase/messaging/sw";

// 初始化Firebase(和前端配置一致)
const firebaseApp = initializeApp({
  apiKey: "你的API_KEY",
  authDomain: "你的AUTH_DOMAIN",
  projectId: "你的PROJECT_ID",
  storageBucket: "你的STORAGE_BUCKET",
  messagingSenderId: "你的MESSAGING_SENDER_ID",
  appId: "你的APP_ID"
});

const messaging = getMessaging(firebaseApp);

// 处理后台推送消息
onBackgroundMessage(messaging, (payload) => {
  console.log('[Service Worker] 收到后台推送:', payload);
  // 自定义通知展示
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: '/你的通知图标.png'
  };
  self.registration.showNotification(notificationTitle, notificationOptions);
});

// 保留你原有的SW逻辑(比如Workbox缓存策略等)
// ... 你的原有代码 ...
  1. 修改前端注册逻辑,只保留自定义SW注册
import { register } from 'register-service-worker'
import { getMessaging, getToken } from "firebase/messaging";

let swRegistration = null;

if (process.env.NODE_ENV === 'production') {
  register('/service-worker.js', {
    registrationOptions: { scope: './' },
    ready (registration) {
      swRegistration = registration;
      console.log('Service worker已激活');
      // 初始化FCM并获取令牌
      initFCM();
    },
    // 保留其他回调(updated、offline等)
    error (error) {
      console.error('Service Worker注册失败:', error)
    }
  })
}

async function initFCM() {
  const permission = await Notification.requestPermission();
  if (permission === 'granted') {
    const messaging = getMessaging();
    const current_token = await getToken(messaging, { 
      vapidKey: '你的VAPID_KEY',
      serviceWorkerRegistration: swRegistration
    });
    await processNewToken(current_token);
  }
}

方案2:为FCM SW设置独立作用域(备选)

如果不想合并代码,可以给FCM的SW设置独立作用域,避免与自定义SW冲突:

  1. 将firebase-messaging-sw.js移到子目录,比如/fcm/firebase-messaging-sw.js
  2. 注册时指定作用域:
const registration = await navigator.serviceWorker.register("/fcm/firebase-messaging-sw.js", {
  scope: "/fcm/"
});
  1. 自定义SW的作用域保持./,确保两者作用域不重叠。

注意:此方案可能限制FCM消息的处理范围,仅在特定场景下使用。


额外注意事项

  • 部署更新后,可在updated回调中提示用户刷新页面,确保浏览器加载新的SW
  • 检查Workbox配置,避免误缓存旧的SW文件
  • 测试时可通过Chrome DevTools的Application > Service Workers手动注销旧SW,验证新逻辑

内容的提问来源于stack exchange,提问作者Richard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:56:34