Firebase Cloud Messaging报错:navigator未定义及浏览器不兼容
实现Firebase Cloud Messaging时遇到的两个问题
错误日志汇总
error - node_modules\@firebase\messaging\dist\esm\index.esm2017.js (1019:0) @ Component.WindowMessagingFactory [as instanceFactory] error - ReferenceError: navigator is not defined at FirebaseProvider (./hooks/useFirebase.tsx:36:87) null error - node_modules\@firebase\messaging\dist\esm\index.esm2017.js (1167:0) @ eval error - unhandledRejection: FirebaseError: Messaging: This browser doesn't support the API's required to use the Firebase SDK. (messaging/unsupported-browser). at eval (webpack-internal:///(sc_client)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:1180:33) { code: 'messaging/unsupported-browser', customData: {} } null
问题1:navigator未定义
原因分析
navigator是浏览器环境专属的全局对象,若项目使用服务端渲染框架(如Next.js),FirebaseProvider会在服务端执行初始化逻辑,此时调用getMessaging(firebase_app)会触发Firebase SDK内部对navigator的访问,导致服务端环境下找不到该对象报错。
解决方案
将Messaging相关的初始化逻辑移到客户端专属的生命周期中(如React的useEffect),同时增加浏览器环境判断:
修改useFirebase.tsx中的FirebaseProvider:
import { useState, useEffect } from 'react'; import { Messaging, getMessaging, getToken, onMessage } from 'firebase/messaging'; // 其他必要导入保持不变 export const FirebaseProvider = ({ children }: { children: JSX.Element }) => { const db = getFirestore(firebase_app); const storage = getStorage(firebase_app); const functions = getFunctions(firebase_app); const auth = getAuth(firebase_app); const [messaging, setMessaging] = useState<Messaging | undefined>(undefined); const [saveMessagingDeviceToken, setSaveMessagingDeviceToken] = useState<(() => void) | undefined>(undefined); useEffect(() => { // 仅在浏览器环境执行Messaging相关逻辑 if (typeof window !== 'undefined' && typeof navigator !== 'undefined') { const msgInstance = getMessaging(firebase_app); setMessaging(msgInstance); // 定义保存设备Token的函数 async function saveToken() { if (!auth.currentUser) return; try { const currentToken = await getToken(msgInstance); if (currentToken) { console.log("Got FCM device token:", currentToken); const tokenRef = doc(db, "fcm_tokens", currentToken); await setDoc(tokenRef, { uid: auth.currentUser.uid }); onMessage(msgInstance, (message) => { console.log( "New foreground notification from Firebase Messaging!", message.notification ); }); } else { requestNotificationsPermissions(); } } catch (error) { console.error("Unable to get messaging token.", error); } } // 请求通知权限函数 async function requestNotificationsPermissions() { console.log("Requesting notifications permission..."); const permission = await Notification.requestPermission(); if (permission === "granted") { console.log("Notification permission granted."); await saveToken(); } else { console.log("Unable to get permission to notify."); } } setSaveMessagingDeviceToken(saveToken); } }, [auth, db]); return ( <FirebaseContext.Provider value={{ auth, db, storage, functions, saveMessagingDeviceToken }} > {children} </FirebaseContext.Provider> ); };
问题2:浏览器不支持FCM API
原因分析
即便在Chrome和开启推送服务的Brave中出现该错误,可能的触发原因包括:
- 项目运行在HTTP协议环境下(FCM要求HTTPS,仅
localhost例外) - 浏览器推送权限未正确授予或被系统限制
- Firebase Messaging的Service Worker未正确配置或注册
- 初始化Messaging前未做浏览器兼容性校验
解决方案
- 确认运行环境协议:确保项目在HTTPS环境下运行(本地开发用
localhost不受限制) - 前置兼容性校验:在初始化Messaging前先验证浏览器支持性,修改
useEffect中的逻辑:useEffect(() => { if (typeof window !== 'undefined' && typeof navigator !== 'undefined') { // 检查浏览器是否支持FCM所需核心API if (!('Notification' in window) || !('serviceWorker' in navigator)) { console.log("当前浏览器不支持FCM推送功能"); return; } // 后续Messaging初始化逻辑... } }, [auth, db]); - 配置Service Worker:确保项目根目录存在
firebase-messaging-sw.js,示例内容如下:importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js'); firebase.initializeApp({ 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(); - 清理旧缓存:若存在旧的Service Worker缓存,可在Chrome开发者工具的
Application > Service Workers面板中强制更新或注销旧缓存
内容的提问来源于stack exchange,提问作者Tsabary
相关产品推荐
相关产品推荐

