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

React Web App无法接收Firebase前台通知问题求助

React + Firebase@8.2.0 前台通知无法接收问题

我在React Web应用中使用firebase@8.2.0实现前台通知功能,但无法接收Firebase控制台发送的消息/通知。按照教程步骤在Firebase控制台发送消息后,教程示例能正常收到通知并在控制台打印日志,但我的测试环境中既没有收到消息,也没有任何日志输出。

我的代码实现

src/firebase.ts

import { useEffect } from 'react';
import firebase from "firebase/app";
import "firebase/messaging";
import { firebaseConfig } from './constants';

if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
} else {
  firebase.app();
}

let messaging: firebase.messaging.Messaging;

if (typeof window !== "undefined") {
  if (firebase.messaging.isSupported()) {
    messaging = firebase.messaging();
  }
}

export const getMessagingToken = async () => {
  let currentToken = "";
  if (!messaging) return;
  try {
    currentToken = await messaging.getToken({
      vapidKey: process.env.REACT_APP_FIREBASE_FCM_VAPID_KEY, // 测试时已硬编码
    });
    console.log("FCM registration token", currentToken);
  } catch (error) {
    console.log("获取令牌时出错:", error);
  }
  return currentToken;
};

export const onMessageListener = () =>
  new Promise((resolve) => {
    messaging.onMessage((payload) => {
      resolve(payload);
    });
  });

App.tsx

import { useEffect } from 'react';
import './App.css';
import { getMessagingToken, onMessageListener } from './firebase';
import logo from './logo.svg';

function App() {
  useEffect(() => {
    getMessagingToken();
  }, []);
  useEffect(() => {
    onMessageListener().then((data) => {
      console.log('收到前台消息:', data);
    });
  });
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          编辑 <code>src/App.tsx</code> 并保存以重新加载。
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          学习React
        </a>
      </header>
    </div>
  );
}

export default App;

已排查的内容

  • firebaseConfig配置正确
  • vapidKey配置正确(测试时已硬编码)
  • Chrome和Firefox均已允许通知权限
  • 已在Firebase控制台的「项目设置 > Web应用」中完成Web应用配置

问题排查与修复方案

1. 修复onMessageListener的订阅逻辑

你的App.tsx中第二个useEffect无依赖数组,会在组件每次重渲染时重复创建订阅,可能导致监听失效。同时原监听函数未做messaging初始化判断,容易报错。

修改src/firebase.ts中的监听函数:

export const onMessageListener = () =>
  new Promise((resolve, reject) => {
    if (!messaging) {
      reject(new Error('Messaging未初始化'));
      return;
    }
    const unsubscribe = messaging.onMessage((payload) => {
      resolve(payload);
    });
    return () => unsubscribe();
  });

修改App.tsx中的订阅逻辑:

useEffect(() => {
  const listenForMessages = async () => {
    try {
      await onMessageListener().then((data) => {
        console.log('收到前台消息:', data);
      });
    } catch (err) {
      console.log('监听消息失败:', err);
    }
  };
  listenForMessages();
}, []);

2. 补充Service Worker配置

Firebase Messaging依赖Service Worker才能正常接收推送,在public目录下创建firebase-messaging-sw.js:

importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js');

firebase.initializeApp({
  // 填入你的firebaseConfig完整内容
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID"
});

const messaging = firebase.messaging();

注意:FCM仅支持HTTPS环境(localhost可豁免),测试时确保运行环境符合要求。

3. 检查Firebase控制台消息配置

  • 发送消息时,选择「单个设备」并填入getMessagingToken输出的令牌,避免批量推送的目标匹配问题。
  • 确保消息包含notification字段,前台监听需要该字段触发回调(纯data消息需自定义处理逻辑)。

4. 验证令牌有效性

删除浏览器缓存和网站数据后,重新获取令牌并再次测试推送。如果令牌获取失败,检查浏览器是否禁用了Service Worker或推送权限。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:15:53