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

ReactJS中Firebase Messaging Token从Promise获取异常求助

React集成Firebase Messaging:解决请求头中Token显示[object Promise]的问题

核心原因

你直接将异步函数getNewToken()赋值给了请求头,而异步函数返回的是Promise对象,所以请求头会显示[object Promise]。必须等待Promise解析完成,拿到实际的Token字符串后再添加到请求头。


解决方案1:单个请求中正确使用async/await

确保发送请求的函数是异步的,先等待Token获取完成,再组装请求头:

// 你的Firebase Token获取函数(内部需正确使用await)
async function getNewToken() {
  const messaging = getMessaging();
  // 必须await getToken,否则返回的还是Promise
  return await getToken(messaging, { vapidKey: '你的VAPID密钥' });
}

// 发送请求的异步函数
async function sendBackendRequest() {
  try {
    // 先等待Token获取完成
    const fcmToken = await getNewToken();
    
    // 此时fcmToken是实际字符串,可直接添加到请求头
    const response = await fetch('https://你的后端接口地址', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'FCM-Token': fcmToken
      },
      body: JSON.stringify({ /* 你的请求体数据 */ })
    });
    
    const result = await response.json();
    console.log('请求成功:', result);
  } catch (err) {
    console.error('获取Token或发送请求出错:', err);
  }
}

解决方案2:全局请求拦截器(以Axios为例)

如果项目用Axios发送请求,可配置全局拦截器,自动在每个请求前获取Token并添加到请求头:

import axios from 'axios';
import { getMessaging, getToken } from "firebase/messaging";

// 创建Axios实例
const apiClient = axios.create({
  baseURL: 'https://你的后端基础URL'
});

// 请求拦截器:每次请求前自动添加Token
apiClient.interceptors.request.use(async (config) => {
  try {
    const fcmToken = await getNewToken();
    if (fcmToken) {
      config.headers['FCM-Token'] = fcmToken;
    }
    return config;
  } catch (err) {
    console.error('拦截器中获取Token失败:', err);
    // 即使Token获取失败,仍允许请求发送(可根据业务需求调整)
    return config;
  }
});

// 封装带缓存的Token获取函数
async function getNewToken() {
  // 先读本地缓存,避免重复请求Firebase
  const cachedToken = localStorage.getItem('fcm_token');
  if (cachedToken) return cachedToken;

  const messaging = getMessaging();
  const newToken = await getToken(messaging, { vapidKey: '你的VAPID密钥' });
  // 缓存Token到本地
  localStorage.setItem('fcm_token', newToken);
  return newToken;
}

// 使用示例
async function fetchUserData() {
  try {
    const res = await apiClient.get('/user/profile');
    console.log(res.data);
  } catch (err) {
    console.error('请求失败:', err);
  }
}

额外优化:处理Token过期/刷新

Firebase Token可能会过期或失效,需监听Token刷新事件及时更新缓存:

import { getMessaging, onTokenRefresh } from "firebase/messaging";

const messaging = getMessaging();
// 监听Token刷新事件
onTokenRefresh(async () => {
  try {
    const newToken = await getToken(messaging, { vapidKey: '你的VAPID密钥' });
    localStorage.setItem('fcm_token', newToken);
    console.log('Token已自动更新:', newToken);
  } catch (err) {
    console.error('更新Token失败:', err);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:45:29