React.js应用收到Firebase Cloud Messaging消息后如何触发Redux action
React.js中收到FCM推送后触发Redux Action的解决方案
完全可以在FCM的回调逻辑中触发Redux Action,你遇到的两个问题均属于逻辑实现问题,对应修复方案如下:
问题1:getToken内触发Action导致无限调用
原因
getToken逻辑如果没有做执行限制,会随着组件重渲染反复执行:触发Action→Redux状态更新→关联组件重渲染→再次执行getToken→再次触发Action,形成死循环,导致大量重复网络请求。
修复方案
将getToken逻辑包裹在空依赖的useEffect中,仅在组件挂载时执行一次,同时增加token缓存校验,避免重复执行逻辑:
import { getToken } from "firebase/messaging"; import { useDispatch } from "react-redux"; import { saveFcmToken } from "./store/notificationSlice"; import { messaging } from "./utils/firebase"; function App() { const dispatch = useDispatch(); useEffect(() => { const initFcmToken = async () => { // 已存储有效token则直接跳过逻辑 const cachedToken = localStorage.getItem("fcm_valid_token"); if (cachedToken) return; const token = await getToken(messaging, { vapidKey: "你的VAPID公钥", }); if (token) { localStorage.setItem("fcm_valid_token", token); // 仅在首次拿到有效token时触发一次Action dispatch(saveFcmToken(token)); } }; initFcmToken(); }, [dispatch]); // dispatch引用稳定,不会触发重复执行 // 其余组件逻辑 }
问题2:onMessage内触发Action不生效
原因
两个常见触发场景问题:
- onMessage仅监听应用处于前台活跃状态时收到的推送,应用后台、锁屏、关闭状态收到的推送不会触发该回调
- 若onMessage在组件内部注册,闭包会捕获旧的dispatch引用,或者组件卸载后监听失效,导致Action无法正常触发
修复方案
将onMessage监听全局注册,直接引入初始化完成的Redux store实例调用dispatch,不依赖组件内的hooks:
// src/utils/fcm.js 全局FCM配置文件 import { initializeApp } from "firebase/app"; import { getMessaging, onMessage } from "firebase/messaging"; import store from "../store"; // 直接引入你导出的Redux store实例 import { receiveFcmPush } from "../store/notificationSlice"; // Firebase初始化逻辑 const firebaseConfig = { // 你的Firebase配置 }; const app = initializeApp(firebaseConfig); export const messaging = getMessaging(app); // 全局注册前台推送监听 onMessage(messaging, (pushPayload) => { // 直接使用store.dispatch触发Action,不受组件生命周期影响 store.dispatch(receiveFcmPush(pushPayload.notification)); });
额外注意事项
- 后台/锁屏状态的推送需要单独注册
onBackgroundMessage回调,同样在回调内直接引入store实例调用dispatch即可 - token有效性校验逻辑不要和getToken耦合,建议设置定时任务或者在接口返回token无效的错误码时再触发校验,避免频繁发送请求
内容的提问来源于stack exchange,提问作者Mohamed Ashraf
相关产品推荐
相关产品推荐

