Firebase原生JS应用中Service Worker注册失败问题排查
问题:Firebase原生JS应用无法注册Service Worker
我开发了一个仅用于初始化并展示Firebase推送通知的JavaScript应用,核心代码如下:
主应用代码(index.js)
import { initializeApp } from "firebase/app"; import { getMessaging, onMessage, getToken } from "firebase/messaging"; const firebaseConfig = { // 配置内容 }; const vapidKey = // vapid密钥; console.log("Here"); // 初始化Firebase const app = initializeApp(firebaseConfig); const messaging = getMessaging(app); Notification.requestPermission().then(function(permission) { console.log('permiss', permission) if (permission === 'granted') { if ('serviceWorker' in navigator) { navigator.serviceWorker .register(new URL('./firebase-messaging-sw.js', import.meta.url), {type: 'module'} ) .then(function (registration) { console.log('Registration successful, scope is:', registration.scope) getToken(messaging,{vapidKey}) .then(function (currentToken) { if (currentToken) { console.log("Get token:",currentToken) document.getElementById("token").innerText=currentToken onMessage(messaging, (payload) => { console.log(payload) }); } }).catch(error => console.error(error)); }) .catch(function (err) { console.log('Service worker registration failed, error:', err) }) } } });
Service Worker代码(firebase-messaging-sw.js)
import { initializeApp } from 'firebase/app'; import { getMessaging } from "firebase/messaging"; import { onBackgroundMessage } from 'firebase/messaging/sw' const firebaseConfig = { // Firebase配置内容 }; const app = initializeApp(firebaseConfig); const messaging = getMessaging(app); onBackgroundMessage(messaging, (payload) => { console.log('[firebase-messaging-sw.js] Received background message ', payload); // 自定义通知内容 const notificationTitle = 'Background Message Title'; const notificationOptions = { body: 'Background message body', icon: 'icon.png' }; // self.registration.showNotification(notificationTitle, notificationOptions); });
报错信息
Service worker registration failed, error: TypeError: ServiceWorker script at https://172.161.10.2:1234/firebase-messaging-sw.js?1715685024290 for scope https://172.161.10.2:1234/ threw an exception during script evaluation.
我无法定位JS中的具体异常,当前使用Parcel部署应用,启动命令为:
npx parcel --https --host 0.0.0.0 --cert=/home/node/ssl/www.crt --key=/home/node/ssl/www.key src/index.html
HTML文件内容
<!DOCTYPE html> <html> <head> <title>Using Push.js to Display Web Browser Notifications</title> <link rel="stylesheet" href="./styles.css"> </head> <body> <h1>Display Web Browser Notifications</h1> <pre><code id="token"></code></pre> <script type="module" src="./index.js" /> </body> </html>
项目依赖配置
{ "name": "firebasedemo", "version": "1.0.0", "description": "", "browserslist": [ "since 2017-06" ], "scripts": { "start": "parcel src/index.html", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "UNLICENCED", "devDependencies": { "parcel": "^2.12.0", "process": "^0.11.10" }, "dependencies": { "firebase": "^10.12.0" } }
请问为何我的Firebase原生JS应用无法注册Service Worker?
解决方案
1. 修复Service Worker模块兼容性问题
注册Service Worker时指定的{type: 'module'}会触发兼容性问题,多数浏览器对模块类型的Service Worker支持不完善,且Firebase消息推送的SW适配逻辑更适合传统脚本模式。
- 修改注册代码,移除
type: 'module'选项:navigator.serviceWorker .register(new URL('./firebase-messaging-sw.js', import.meta.url)) - 改用Firebase的compat兼容版本编写Service Worker,避免模块导入冲突:
import { initializeApp } from 'firebase/app/compat'; import { getMessaging, onBackgroundMessage } from 'firebase/messaging/sw/compat'; const firebaseConfig = { // 你的Firebase完整配置 }; const app = initializeApp(firebaseConfig); const messaging = getMessaging(app); onBackgroundMessage(messaging, (payload) => { console.log('[firebase-messaging-sw.js] Received background message ', payload); const notificationTitle = 'Background Message Title'; const notificationOptions = { body: 'Background message body', icon: 'icon.png' }; self.registration.showNotification(notificationTitle, notificationOptions); });
2. 配置Parcel正确处理Service Worker
Parcel默认不会自动识别Service Worker文件类型,需手动添加配置:
- 在项目根目录创建
.parcelrc文件,添加Service Worker转换器:{ "extends": "@parcel/config-default", "transformers": { "service-worker:*": ["@parcel/transformer-service-worker"] } } - 确保
firebase-messaging-sw.js放在src目录下,与主应用代码同目录,避免路径解析错误。
3. 查看Service Worker的详细错误日志
浏览器主控制台不会显示SW的具体报错,需通过开发者工具的专属面板查看:
- 打开Chrome开发者工具,切换到
Application标签 - 左侧菜单选择
Service Workers,找到对应的SW条目 - 点击
Inspect打开SW独立控制台,即可看到初始化时的具体异常(如导入失败、配置错误等)
4. 检查配置完整性
- 确认
vapidKey已赋值完整的公钥字符串(以BK开头),不可留空或只写注释 - 核对Firebase配置中的
apiKey、authDomain、projectId等字段,确保与Firebase控制台的配置完全一致
5. 修复HTML脚本标签问题
HTML中的<script>标签不可自闭合,需修改为标准闭合格式:
<script type="module" src="./index.js"></script>
自闭合标签会导致HTML解析异常,可能间接影响Service Worker的加载流程。
内容的提问来源于stack exchange,提问作者Dimitrios Desyllas
相关产品推荐
相关产品推荐

