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

如何在CRA5中用Firebase v9单Service Worker实现Web推送并解决getToken未触发问题

解决Create React App 5 + Firebase v9 Web推送通知getToken不触发问题

问题核心原因

  • Firebase v9采用模块化架构,Service Worker环境下的导入方式和v8完全不同
  • Firebase默认会自动寻找firebase-messaging-sw.js文件作为消息服务工作者,若你用CRA5默认的service-worker.js,需要手动配置告知Firebase使用该文件

具体解决方案

1. 调整Service Worker中的Firebase导入与初始化

在CRA5生成的service-worker.js中,替换原有初始化代码为以下模块化写法:

// 导入Firebase SW专用模块
import { initializeApp } from 'firebase/app';
import { getMessaging, onBackgroundMessage } from 'firebase/messaging/sw';

// 初始化Firebase应用
const firebaseApp = initializeApp({
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGE_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
});

// 获取messaging实例
const messaging = getMessaging(firebaseApp);

// 监听后台消息(可选,处理应用在后台时的推送)
onBackgroundMessage(messaging, (payload) => {
  console.log('后台消息接收:', payload);
  // 自定义通知展示逻辑
  const notificationTitle = payload.notification.title;
  const notificationOptions = {
    body: payload.notification.body,
    icon: '/logo192.png'
  };

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

2. 在客户端代码中配置Firebase使用自定义Service Worker

在你的客户端初始化Firebase的文件(比如firebase.js或App.js)中,需要手动注册service-worker并告知Firebase使用该注册实例:

import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';

// 初始化客户端Firebase应用
const firebaseApp = initializeApp({
  // 同样的配置参数
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGE_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID,
  measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID
});

const messaging = getMessaging(firebaseApp);

// 注册CRA5的service-worker,并关联到Firebase
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js')
    .then((registration) => {
      // 告知Firebase使用该service worker注册实例
      messaging.useServiceWorker(registration);
      
      // 尝试获取推送token
      getToken(messaging, { vapidKey: '你的VAPID公钥' })
        .then((currentToken) => {
          if (currentToken) {
            console.log('推送Token:', currentToken);
            // 这里可以把token发送到后端保存
          } else {
            console.log('没有获取到推送权限,请授权');
          }
        })
        .catch((err) => {
          console.log('获取token失败:', err);
        });
    })
    .catch((err) => {
      console.log('Service Worker注册失败:', err);
    });
}

// 监听前台消息(可选)
onMessage(messaging, (payload) => {
  console.log('前台消息接收:', payload);
});

3. 移除不必要的firebase-messaging-sw.js文件

因为我们已经把所有Firebase消息逻辑放到了CRA5默认的service-worker.js中,不需要再保留空的firebase-messaging-sw.js,直接删除即可。

关键注意事项

  • 确保你的VAPID公钥正确配置,该公钥可以在Firebase控制台的「云消息传递」>「Web配置」中获取
  • 环境变量在CRA5的service-worker.js中是可用的,因为该文件会被Webpack处理,无需额外配置
  • 测试时需要在HTTPS环境下(本地开发可以用npm start,CRA默认提供HTTPS)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 02:17:46