NextJS部署后FCM Token获取失败:默认Service Worker注册报错
错误详情
FirebaseError: Messaging: 无法注册默认Service Worker。SyntaxError: Unexpected token '{'. import call expects exactly one argument. (messaging/failed-service-worker-registration).
f —_app-6e5ce7543176b121599c.js:1:8509
create —_app-6e5ce7543176b121599c.js:1:8994
(anonymous function) —_app-6e5ce7543176b121599c.js:1:639312
asyncFunctionResume
(anonymous function)
promiseReactionJobWithoutPromise.
promiseReactionJob
本地开发环境可正常获取FCM Token,但Next.js项目构建启动或部署到服务器后触发该错误,尝试多种方案未解决。
解决方案
1. 修复Service Worker语法兼容性
生产环境浏览器可能不支持未转译的ES模块语法(比如解构导入),需调整SW文件或配置Next.js转译:
- 将
firebase-messaging-sw.js中的ES模块语法替换为CommonJS(比如const { initializeApp } = require('firebase/app')) - 在
next.config.js中添加转译配置:module.exports = { transpilePackages: ['firebase'], async headers() { return [ { source: '/firebase-messaging-sw.js', headers: [{ key: 'Content-Type', value: 'application/javascript' }], }, ]; }, };
2. 确认SW文件位置正确
Next.js要求静态资源放在public目录下,firebase-messaging-sw.js必须放在项目根目录的public文件夹中,部署后通过https://你的域名/firebase-messaging-sw.js能直接访问到正确代码。
3. 避免Next.js自带SW冲突
如果用了next-pwa这类插件,需排除FCM的SW文件:
const withPWA = require('next-pwa')({ dest: 'public', exclude: [({ asset }) => asset.name === 'firebase-messaging-sw.js'], });
4. 手动注册Service Worker
放弃FCM默认注册逻辑,手动指定SW文件:
import { getMessaging, registerServiceWorker } from 'firebase/messaging'; const messaging = getMessaging(); registerServiceWorker(messaging, { serviceWorkerUrl: '/firebase-messaging-sw.js', }) .then(() => console.log('SW注册成功')) .catch(err => console.error('SW注册失败', err));
5. 同步Firebase与Next.js版本兼容性
尝试升级或降级Firebase SDK版本,确保和当前Next.js版本适配:
npm install firebase@latest # 或指定稳定版本:npm install firebase@9.23.0
内容的提问来源于stack exchange,提问作者Atik Habib

