Next.js集成FCM(v9)遇‘Service messaging is not available’错误求解决
解决Next.js集成FCM v9出现“Service messaging is not available”错误
这个错误核心原因是FCM依赖浏览器的Service Worker API,无法在Next.js的服务端(SSR/SSG)环境中初始化,只要调整代码运行环境并补全配置,完全可以在v9版本正常使用,不需要降级到v8。以下是具体解决步骤:
1. 限制FCM仅在客户端环境初始化
Next.js会在服务端预渲染组件,直接在全局初始化FCM会触发服务端无浏览器API的报错,可通过两种方式规避:
方式一:在Firebase配置文件中判断浏览器环境
修改你的Firebase.js:
import { initializeApp } from "firebase/app"; import { getMessaging, getToken } from "firebase/messaging"; const firebaseConfig = { apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, // 注意检查变量名拼写 appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }; let messaging = null; // 仅在浏览器环境初始化FCM if (typeof window !== 'undefined') { const app = initializeApp(firebaseConfig); messaging = getMessaging(app); } export { messaging };
方式二:在客户端组件中用useEffect初始化(Next.js 13+推荐)
创建标记'use client'的客户端组件,在组件挂载时初始化FCM:
'use client'; import { useEffect } from 'react'; import { initializeApp } from "firebase/app"; import { getMessaging, getToken } from "firebase/messaging"; const firebaseConfig = { /* 你的Firebase配置 */ }; export default function FCMInitializer() { useEffect(() => { const app = initializeApp(firebaseConfig); const messaging = getMessaging(app); // 传入VAPID密钥获取推送token getToken(messaging, { vapidKey: '你的VAPID公钥' }) .then(currentToken => { if (currentToken) { console.log('推送Token:', currentToken); // 可将token发送到后端存储 } else { console.log('请授权浏览器通知权限'); } }).catch(err => { console.error('获取Token失败:', err); }); }, []); return null; // 该组件无需渲染UI }
在根组件(如layout.js或_app.js)中引入这个组件即可。
2. 配置VAPID密钥
FCM v9必须使用VAPID密钥才能在Web端获取推送Token:
- 登录Firebase控制台 → 目标项目 → 项目设置 → 云消息传递 → Web配置(无配置则先添加Web应用)
- 复制“Web推送证书”下的VAPID公钥,在调用
getToken时传入(如上述代码所示)
3. 配置Service Worker
在Next.js的public目录下创建firebase-messaging-sw.js文件,用于处理后台推送消息:
// 注意:此处firebase版本需与项目安装的v9版本一致 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'); const firebaseConfig = { /* 你的Firebase配置 */ }; firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging(); // 处理后台推送消息 messaging.onBackgroundMessage(payload => { const notificationTitle = payload.notification.title; const notificationOptions = { body: payload.notification.body, icon: '/你的图标路径.png' }; self.registration.showNotification(notificationTitle, notificationOptions); });
4. 检查环境变量
确认所有NEXT_PUBLIC_前缀的环境变量拼写正确,比如messagingSenderId对应的环境变量名是否为NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID(避免拼写错误导致配置无效)。
内容的提问来源于stack exchange,提问作者Luís Fernandes
相关产品推荐
相关产品推荐

