You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13 App Router中FCM推送配置问题求助

Next.js 13 App Router 正确集成FCM(支持前后台推送+无构建错误)

核心问题复盘

之前的构建错误是因为Firebase SDK在SSR环境(服务器端渲染)中执行,而SDK仅支持浏览器环境;后台推送失效则是因为Service Worker的配置未适配Next.js 13 App Router的静态资源规则,且后台消息处理逻辑未正确挂载到Service Worker上。

完整配置方案

1. Firebase客户端初始化(utils/firebase.ts)

必须标记为客户端组件,且仅在浏览器环境初始化:

'use client';

import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';

// Firebase配置参数,建议从环境变量读取
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
};

let messaging: ReturnType<typeof getMessaging> | null = null;

// 仅在浏览器环境初始化Firebase
if (typeof window !== 'undefined') {
  const app = initializeApp(firebaseConfig);
  messaging = getMessaging(app);
}

export { messaging, getToken, onMessage };

2. Service Worker配置(public/firebase-messaging-sw.js)

注意要正确引入Firebase SDK的CDN版本,且配置后台消息处理器:

// 引入Firebase SDK的Service Worker版本
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(配置参数要和客户端一致)
firebase.initializeApp({
  apiKey: '<你的API_KEY>',
  authDomain: '<你的AUTH_DOMAIN>',
  projectId: '<你的PROJECT_ID>',
  storageBucket: '<你的STORAGE_BUCKET>',
  messagingSenderId: '<你的MESSAGING_SENDER_ID>',
  appId: '<你的APP_ID>'
});

const messaging = firebase.messaging();

// 后台消息处理:当APP处于后台/关闭时触发
messaging.onBackgroundMessage((payload) => {
  console.log('后台推送消息:', payload);
  const notificationTitle = payload.notification?.title || '新消息';
  const notificationOptions = {
    body: payload.notification?.body || '您有一条新通知',
    icon: '/firebase-logo.png' // 替换为你的通知图标路径
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});

3. 客户端组件中注册Service Worker并处理前台消息

在需要使用推送的客户端组件(比如app/layout.tsx或专门的PushNotification.tsx)中添加以下逻辑:

'use client';

import { useEffect } from 'react';
import { messaging, getToken, onMessage } from '@/utils/firebase';

export default function PushNotification() {
  useEffect(() => {
    if (!messaging) return;

    // 注册Service Worker
    async function registerServiceWorker() {
      if ('serviceWorker' in navigator) {
        try {
          const registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js');
          console.log('Service Worker注册成功:', registration);
        } catch (error) {
          console.error('Service Worker注册失败:', error);
        }
      }
    }

    // 获取FCM Token
    async function fetchFCMToken() {
      try {
        const token = await getToken(messaging, {
          vapidKey: '<你的VAPID_KEY>' // 从Firebase控制台获取
        });
        if (token) {
          console.log('FCM Token:', token);
          // 这里可以把Token发送到你的后端存储
        }
      } catch (error) {
        console.error('获取FCM Token失败:', error);
      }
    }

    // 处理前台消息
    const unsubscribe = onMessage(messaging, (payload) => {
      console.log('前台推送消息:', payload);
      // 自定义前台消息展示逻辑,比如弹出Toast
    });

    registerServiceWorker();
    fetchFCMToken();

    return () => unsubscribe();
  }, []);

  return null; // 组件无需渲染内容
}

4. 环境变量配置

在.env.local中添加Firebase的公开配置(前缀必须是NEXT_PUBLIC_,否则客户端无法读取):

NEXT_PUBLIC_FIREBASE_API_KEY=xxx
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=xxx
NEXT_PUBLIC_FIREBASE_PROJECT_ID=xxx
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=xxx
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=xxx
NEXT_PUBLIC_FIREBASE_APP_ID=xxx

关键注意事项

  • 所有Firebase相关代码必须放在客户端组件中(标记'use client'),避免SSR阶段执行
  • Service Worker文件必须放在public根目录,否则Next.js的静态资源路由会导致无法访问
  • 后台消息必须用onBackgroundMessage在Service Worker中处理,onmessage仅适用于前台场景
  • VAPID Key需要从Firebase控制台的「Cloud Messaging」页面获取(Web配置部分)
  • 生产部署前,确保Firebase控制台已添加你的网站域名到「授权域名」列表

内容的提问来源于stack exchange,提问作者shubham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:25:13