AngularFireMessaging生产环境启用buildOptimizer后报错:Hn.messaging不是函数
AngularFireMessaging生产环境buildOptimizer开启时报错'Hn.messaging is not a function'的解决方案
问题背景
在Angular应用中基于AngularFireMessaging实现推送通知,开发环境运行正常,但生产环境开启buildOptimizer: true时触发错误:'Hn.messaging is not a function in angular-fire-compat-messaging'。相关代码如下:
Firebase消息服务代码
@Injectable({ providedIn: 'root' }) export class FirebaseMessagingService { public constructor(private afMessaging: AngularFireMessaging) {} public listen(): void { if (!this.browserService.isBrowser) { return; } this.afMessaging.messages.subscribe(); } }
Firebase Service Worker文件(firebase-messaging-sw.js)
importScripts('https://www.gstatic.com/firebasejs/7.23.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/7.23.0/firebase-messaging.js'); var firebaseConfig = { apiKey: '', authDomain: '', projectId: '', storageBucket: '', messagingSenderId: '', appId: '', }; firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging();
AppModule配置
imports: [ AngularFireModule.initializeApp(environment.FIREBASE_CONFIG), AngularFireMessagingModule, ]
可行解决方案
1. 对齐Firebase SDK与AngularFire版本
当前Service Worker中使用的Firebase SDK(7.23.0)可能与项目依赖的AngularFire版本不兼容,导致buildOptimizer优化时破坏了必要的调用逻辑:
- 查看项目
package.json中firebase和@angular/fire的版本,确保两者版本匹配 - 修改
firebase-messaging-sw.js中的SDK版本,与项目依赖的firebase版本保持一致,例如:importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js');
2. 配置Angular优化白名单
在angular.json的生产构建配置中,将相关Firebase库加入允许的CommonJS依赖名单,避免buildOptimizer误删代码:
"configurations": { "production": { "buildOptimizer": true, "allowedCommonJsDependencies": [ "firebase", "@angular/fire/compat/messaging" ], // 其他生产配置... } }
3. 迁移到AngularFire模块化API(推荐)
如果使用的是AngularFire v7+,建议放弃compat兼容模式,使用Firebase官方模块化API,该模式更适配Angular的优化工具:
- 更新依赖到最新版本的
@angular/fire和firebase(v9+) - 修改消息服务代码为模块化写法:
import { Injectable } from '@angular/core'; import { getMessaging, onMessage, Messaging } from '@angular/fire/messaging'; @Injectable({ providedIn: 'root' }) export class FirebaseMessagingService { private messaging: Messaging | null = null; constructor() { if (typeof window !== 'undefined') { this.messaging = getMessaging(); } } listen(): void { if (!this.messaging) return; onMessage(this.messaging, (payload) => { // 处理前台消息逻辑 console.log('收到前台推送消息:', payload); }); } } - 更新Service Worker文件为兼容模块化的版本:
importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js'); const firebaseConfig = { // 你的Firebase配置 }; firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging();
4. 调整Service Worker初始化时机
确保在Firebase初始化完成后再调用消息监听方法,避免过早执行导致的未定义错误:
// app.component.ts import { Component, OnInit } from '@angular/core'; import { FirebaseMessagingService } from './firebase-messaging.service'; import { AngularFireMessaging } from '@angular/fire/compat/messaging'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { constructor( private messagingService: FirebaseMessagingService, private afMessaging: AngularFireMessaging ) {} ngOnInit(): void { // 先获取推送令牌确保Firebase初始化完成,再启动监听 this.afMessaging.requestToken.subscribe({ next: () => this.messagingService.listen(), error: (err) => console.error('请求令牌失败:', err) }); } }
内容的提问来源于stack exchange,提问作者Matias Ahumada
相关产品推荐
相关产品推荐

