Angular集成Firebase FCM遇Service Worker注册失败,求Token获取方案
解决FCM集成中Service Worker注册失败及Token生成问题
问题背景
开发需接收Firebase通知的Angular网页,集成FCM获取消息Token时,出现Service Worker注册失败错误:
Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('http://localhost:4200/firebase-cloud-messaging-push-scope') with script ('http://localhost:4200/firebase-messaging-sw.js'): ServiceWorker script evaluation failed (messaging/failed-service-worker-registration).
错误修复方案
1. 修正Service Worker脚本API兼容问题
Firebase v10+已弃用setBackgroundMessageHandler,需替换为新版API,同时修正初始化逻辑。更新firebase-messaging-sw.js代码:
importScripts('https://www.gstatic.com/firebasejs/12.9.1/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/12.9.1/firebase-messaging.js'); const firebaseConfig = { apiKey: "Myapikey", authDomain: "MyDomain", databaseURL: "myDatabseUrl", projectId: "my ProjectID", storageBucket: "My Storage", messagingSenderId: "MessagingId", appId: "AppId", measurementId: "Measure ID" }; // 初始化Firebase实例 const app = firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging(app); // 监听后台消息 messaging.onBackgroundMessage((payload) => { console.log('[firebase-messaging-sw.js] 收到后台消息: ', payload); const notificationTitle = payload.notification?.title || '后台消息通知'; const notificationOptions = { body: payload.notification?.body || '后台消息内容', icon: '/firebase-logo.png' }; return self.registration.showNotification(notificationTitle, notificationOptions); });
2. 确保Service Worker文件位置正确
- 将
firebase-messaging-sw.js放在Angular项目的src/根目录(与index.html同级)。 - 修改
angular.json的assets配置,确保构建时将该文件复制到输出目录:
"assets": [ "src/favicon.ico", "src/assets", "src/firebase-messaging-sw.js" // 添加此行 ]
3. 移除重复的Firebase初始化
你的FirebaseServiceService中同时手动初始化了Firebase和使用AngularFire的初始化,导致冲突。修改Messagingservice.ts:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { AngularFireMessaging } from "@angular/fire/compat/messaging"; @Injectable({ providedIn: 'root' }) export class FirebaseServiceService { currentMessage = new BehaviorSubject<any>(null); constructor(private angularfireMessaging: AngularFireMessaging) { } requestPermission() { this.angularfireMessaging.requestPermission.subscribe( () => this.getToken(), (error) => console.error("无法获取通知权限: ", error) ) } getToken() { this.angularfireMessaging.requestToken.subscribe( (token) => { console.log("FCM Token: ", token); // 此处可将Token发送至后端存储 }, (error) => console.error("获取Token失败: ", error) ) } receiveMessage() { this.angularfireMessaging.messages.subscribe( (payload) => { console.log('收到新消息: ', payload); this.currentMessage.next(payload); } ) } }
4. 满足HTTPS环境要求
FCM要求生产环境必须使用HTTPS,本地开发使用localhost不受限制;若用自定义域名测试,需配置HTTPS证书。
FCM Token生成流程
- 申请用户授权:调用
requestPermission()触发浏览器通知权限弹窗,获取用户许可。 - 获取Token:权限通过后,调用
getToken()获取FCM设备Token。 - 存储Token:将Token发送至后端服务器,用于后续定向推送消息。
- 监听Token更新:Token可能因过期或设备变更刷新,需监听变化并同步到后端:
this.angularfireMessaging.tokenChanges.subscribe( (token) => { if (token) { console.log("Token已更新: ", token); // 同步更新后端存储的Token } } )
验证修复效果
- 重启Angular开发服务器:
ng serve。 - 打开浏览器控制台,确认无Service Worker注册错误。
- 检查控制台输出的FCM Token,确认Token生成成功。
内容的提问来源于stack exchange,提问作者Yousuf iqbal
相关产品推荐
相关产品推荐

