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

在极简React应用中无法获取FCM token的问题求助

解决CRA PWA TypeScript项目中FCM Service Worker MIME类型错误问题

问题根源

你将firebase-messaging-sw.js放在了项目根目录,但CRA仅会把public目录下的文件识别为静态资源。访问根目录文件时,会被React路由 fallback 到index.html,返回text/html类型,导致Service Worker注册失败。

修复步骤

  • 移动Service Worker文件:把firebase-messaging-sw.js移到项目的public目录下,此时访问路径http://localhost:3000/firebase-messaging-sw.js会返回正确的application/javascript类型。
  • 明确指定FCM的Service Worker:在Firebase初始化代码中,手动注册并指定该Service Worker,避免和CRA默认的PWA Service Worker冲突。

修改后的App.tsx示例

import React, { useEffect } from 'react';
import './App.css';
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';

// 替换为你的Firebase配置
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
};

const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);

function App() {
  useEffect(() => {
    const requestPermissionAndGetToken = async () => {
      const permission = await Notification.requestPermission();
      if (permission === 'granted') {
        try {
          // 手动注册FCM的Service Worker并获取Token
          const token = await getToken(messaging, {
            vapidKey: "YOUR_VAPID_KEY", // 从Firebase控制台获取
            serviceWorkerRegistration: await navigator.serviceWorker.register('/firebase-messaging-sw.js')
          });
          console.log('FCM Token:', token);
        } catch (error) {
          console.error('获取Token失败:', error);
        }
      }
    };

    requestPermissionAndGetToken();

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

  return (
    <div className="App">
      <h1>FCM测试页面</h1>
    </div>
  );
}

export default App;

public目录下的firebase-messaging-sw.js示例

// 引入对应版本的Firebase兼容库(需和项目中安装的Firebase版本匹配)
importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js');

const firebaseConfig = {
  // 和App.tsx中一致的配置
};

firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();

// 可选:处理后台消息推送
messaging.onBackgroundMessage((payload) => {
  const notificationTitle = payload.notification?.title || '新消息';
  const notificationOptions = {
    body: payload.notification?.body || '收到一条后台消息',
    icon: '/logo192.png' // 使用项目public目录下的图标
  };

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

额外注意事项

  • 确保firebase-messaging-sw.js中引入的Firebase版本和项目依赖的版本一致,避免兼容性问题。
  • 若不需要CRA默认的PWA Service Worker,可在src/index.tsx中注释掉serviceWorkerRegistration.register()相关代码,减少冲突。
  • 测试时,localhost环境无需HTTPS(Chrome例外允许),正式环境必须使用HTTPS才能正常注册Service Worker。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:50:25