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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:15:24