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
相关产品推荐
相关产品推荐

