Angular集成FCM:Token生成成功但无法接收推送消息求助
问题
我用模块化方法把Firebase Cloud Messaging (FCM)集成到Angular应用里,FCM Token已经成功生成,Firebase控制台也显示消息发送成功,但客户端就是收不到消息。
我的app.component.ts代码
import { Component, inject, OnInit } from '@angular/core'; import { Messaging, getToken, onMessage, MessagePayload, } from '@angular/fire/messaging'; import { BehaviorSubject } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent implements OnInit { title = 'PushNotes'; private readonly _messaging = inject(Messaging); mesage = Messaging; private readonly _message = new BehaviorSubject<unknown | undefined>( undefined ); constructor() {} ngOnInit() { Notification.requestPermission().then((permission) => { if (permission === 'granted') console.log('Permission granted'); else if (permission === 'denied') console.log('Permission denied'); }); debugger; getToken(this._messaging) .then((token) => { console.log('Token', token); }) .catch((error) => console.log('Token error', error)); onMessage(this._messaging, (payload: MessagePayload) => { console.log('Message received', payload); this._message.next(payload); }); } onClickIcon(): void { debugger; console.log('Icon clicked!'); onMessage(this._messaging, (payload: MessagePayload) => { console.log('Message received', payload); this._message.next(payload); }); } }
解决方法
1. 区分前后台消息处理逻辑
onMessage 只负责监听应用处于前台时的消息。如果应用在后台或完全关闭,必须配置Service Worker才能接收推送。
2. 配置Firebase Service Worker
在项目根目录创建firebase-messaging-sw.js文件,填入以下内容(替换成你的Firebase配置):
importScripts('https://www.gstatic.com/firebasejs/9.22.0/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/9.22.0/firebase-messaging-compat.js'); firebase.initializeApp({ apiKey: "你的API_KEY", authDomain: "你的AUTH_DOMAIN", projectId: "你的PROJECT_ID", storageBucket: "你的STORAGE_BUCKET", messagingSenderId: "你的MESSAGING_SENDER_ID", appId: "你的APP_ID" }); const messaging = firebase.messaging(); // 处理后台消息 messaging.onBackgroundMessage(function(payload) { console.log('后台收到消息:', payload); const notificationTitle = payload.notification.title; const notificationOptions = { body: payload.notification.body, icon: '/assets/icon.png' // 替换成你的通知图标路径 }; self.registration.showNotification(notificationTitle, notificationOptions); });
同时确保你的Angular项目启用了Service Worker:
- 安装依赖:
npm install @angular/service-worker - 在
angular.json的build配置中开启serviceWorker: true
3. 移除冗余的消息监听
你在ngOnInit和onClickIcon里重复调用了onMessage,这会导致重复监听,保留ngOnInit里的一次即可。修改后的组件代码:
import { Component, inject, OnInit } from '@angular/core'; import { Messaging, getToken, onMessage, MessagePayload, } from '@angular/fire/messaging'; import { BehaviorSubject } from 'rxjs'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent implements OnInit { title = 'PushNotes'; private readonly _messaging = inject(Messaging); private readonly _message = new BehaviorSubject<unknown | undefined>(undefined); message$ = this._message.asObservable(); // 暴露给模板使用 ngOnInit() { Notification.requestPermission().then((permission) => { if (permission === 'granted') { console.log('通知权限已授予'); this.initFCM(); } else { console.log('通知权限已拒绝'); } }); } private initFCM(): void { // 获取Token getToken(this._messaging) .then((token) => console.log('FCM Token:', token)) .catch((error) => console.log('获取Token失败:', error)); // 监听前台消息 onMessage(this._messaging, (payload: MessagePayload) => { console.log('前台收到消息:', payload); this._message.next(payload); // 前台手动弹出通知(可选) if (payload.notification) { new Notification(payload.notification.title, { body: payload.notification.body, icon: payload.notification.icon || '/assets/icon.png' }); } }); } onClickIcon(): void { console.log('图标被点击!'); // 这里不需要重复添加监听 } }
4. 检查消息格式与测试环境
- Firebase控制台发送消息时,建议同时填写通知和数据字段,确保前后台都能触发处理
- 必须在HTTPS环境测试,本地开发用
ng serve --ssl启动 - 不要在隐身窗口测试,部分浏览器会限制Service Worker功能
内容的提问来源于stack exchange,提问作者Sarmad
相关产品推荐
相关产品推荐

