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

Angular2 PWA集成Firebase Messaging获取Token失败,报错缺少认证凭证

解决Angular PWA(NGSW)中Firebase Messaging获取Token失败的问题

我之前也碰到过一模一样的情况——用Angular自带的NGSW做PWA,调用firebase.messaging().getToken()就报messaging/token-subscribe-failed Request is missing required authentication credential错误,但用SwPush却能正常拿到订阅并推送。核心问题其实是Firebase Messaging的默认Service Worker和Angular的NGSW冲突了,而且Firebase的Token获取流程依赖它自己的SW逻辑,直接用NGSW的话认证凭证没法正确传递。

下面给你两个可行的解决方案:


方案一:让Firebase Messaging复用Angular的NGSW

既然你的PWA已经依赖NGSW,没必要再让Firebase注册一个独立的Service Worker。我们可以让Firebase使用Angular已经注册好的SW实例,这样就能兼容Token获取流程:

  1. 先确保你已经初始化了Firebase App,然后获取Angular的Service Worker注册对象
  2. 把这个注册对象传给Firebase Messaging的useServiceWorker方法

代码示例(可以放在app.component.ts或者专门的推送服务里):

import { Component, OnInit } from '@angular/core';
import { SwPush } from '@angular/service-worker';
import firebase from 'firebase/app';
import 'firebase/messaging';

// 你的Firebase配置
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_SENDER_ID", // 这个必须有,从Firebase控制台拿
  appId: "YOUR_APP_ID"
};

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  constructor(private swPush: SwPush) {}

  ngOnInit(): void {
    // 初始化Firebase
    firebase.initializeApp(firebaseConfig);

    // 获取Angular已经注册的SW实例
    navigator.serviceWorker.getRegistration().then(registration => {
      if (registration) {
        // 让Firebase Messaging使用这个SW
        firebase.messaging().useServiceWorker(registration);
        
        // 现在再尝试获取Token
        firebase.messaging().getToken({ vapidKey: "YOUR_VAPID_PUBLIC_KEY" })
          .then(token => console.log("Firebase Token获取成功:", token))
          .catch(err => console.error("Token获取失败:", err));
      }
    });
  }
}

注意:这里的vapidKey需要和你Firebase控制台里配置的一致,或者用Firebase生成的VAPID公钥(在项目设置>云消息传递>Web配置里能找到)。


方案二:继续使用SwPush,结合Firebase存储订阅信息

既然你已经能用SwPush.requestSubscription()拿到订阅,并且通过Web Push库发送成功,完全可以继续用这个方案,同时把订阅信息同步到Firebase(比如Firestore),方便后续从Firebase触发推送:

  1. 用SwPush获取订阅后,将订阅对象转成JSON存储到Firestore
  2. 在Firebase Cloud Functions中读取这些订阅,用web-push库发送消息

代码示例(存储订阅):

import { Injectable } from '@angular/core';
import { SwPush } from '@angular/service-worker';
import { AngularFirestore } from '@angular/fire/firestore';

@Injectable({ providedIn: 'root' })
export class PushNotificationService {
  private readonly VAPID_PUBLIC_KEY = "YOUR_VAPID_PUBLIC_KEY";

  constructor(private swPush: SwPush, private firestore: AngularFirestore) {}

  requestSubscription(): void {
    this.swPush.requestSubscription({ serverPublicKey: this.VAPID_PUBLIC_KEY })
      .then(subscription => {
        // 将订阅存储到Firestore
        return this.firestore.collection('pushSubscriptions').add(subscription.toJSON());
      })
      .then(docRef => console.log("订阅已存储,ID:", docRef.id))
      .catch(err => console.error("订阅请求失败:", err));
  }
}

这个方案的好处是不用改动现有SW逻辑,直接复用Angular的SwPush,适合已经搭建好Web Push推送流程的场景。


为什么原来的getToken会报错?

Firebase Messaging默认会注册自己的Service Worker(firebase-messaging-sw.js),但Angular的NGSW已经是当前激活的SW,两者会冲突。而且Firebase的Token获取流程需要它自己的SW来处理认证凭证的传递,NGSW没有集成这些逻辑,所以就会出现“缺少认证凭证”的错误。

内容的提问来源于stack exchange,提问作者majodi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:23:58