ReactJS集成Firebase Messaging后网站前台无法接收推送通知
问题原因&修复方案
监听注册逻辑未用副作用钩子包裹
你当前将messaging.onMessage()直接写在组件函数体内,只要App组件触发重渲染,就会重新创建messaging实例、销毁旧监听重新注册,直接导致回调无法触发。未使用提前初始化完成的messaging实例
如果你的firebase初始化逻辑封装在./clients/firebase文件中,直接在App组件内调用firebase.messaging()创建实例,可能出现firebase尚未完成初始化、实例无效的问题。缺少监听销毁逻辑
未在组件卸载时销毁onMessage监听,容易引发内存泄漏导致监听异常。
具体修改步骤
- 先修改你的firebase配置文件(
./clients/firebase.js),导出已经初始化完成的messaging实例:
// ./clients/firebase.js 补充内容 import 'firebase/messaging' // 保留你原有firebase初始化逻辑 const firebaseApp = firebase.initializeApp(你的firebase配置项) export const messaging = firebase.messaging(firebaseApp) // 原有getToken逻辑保持不变
- 修改App.js代码如下:
import React,{useState, useEffect} from 'react'; import { ToastContainer } from 'react-toastify'; import Router from './components/Router'; import Auth from './containers/Auth'; import Form from './containers/Form'; import {getToken, messaging} from './clients/firebase'; import DashboardPage from './containers/Dashboard'; import { ROUTES } from './constants'; function App() { const [isTokenFound, setTokenFound] = useState(false); const [notification, setNotification] = useState({title: '', body: ''}); // getToken放到useEffect中仅执行一次 useEffect(() => { getToken(setTokenFound); }, []) // onMessage注册逻辑放到useEffect中,组件卸载时自动销毁监听 useEffect(() => { if (!messaging) return const unSubscribe = messaging.onMessage(payload => { console.log('received', payload); }); return () => unSubscribe() }, []); return (<> <Router> <Auth path={ROUTES.AUTH.CHILDREN} /> <DashboardPage path={ROUTES.DASHBOARD.CHILDREN} /> <Form path={ROUTES.FORMS.CHILDREN} /> </Router> <ToastContainer /> </> ); } export default App;
额外排查点
如果修改后依然无法触发回调,检查你发送的测试推送payload,不要仅携带notification字段,同时携带data字段测试,部分Firebase版本纯通知类型的前台消息不会触发onMessage回调。
内容的提问来源于stack exchange,提问作者mike hennessy
相关产品推荐
相关产品推荐

