ReactJS+Webpack项目集成Firebase Cloud Messaging遇阻求助
Let's break down your issues one by one and fix them step by step—you're close, just a few misconfigurations and incorrect Service Worker code are blocking you.
1. Fix the Service Worker (sw.js) Code
Your current sw.js has critical mistakes because it’s trying to run browser-context code inside a Service Worker:
- You can’t call
navigator.serviceWorker.register()from within a Service Worker (it’s already the worker itself) - You’re using the regular Firebase SDK instead of the Service Worker-specific build
Here’s the corrected sw.js:
// Import SW-compatible Firebase SDKs via CDN (or use npm equivalents) importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js'); // Initialize Firebase const firebaseConfig = { apiKey: '***********************', authDomain: '*****.firebaseapp.com', databaseURL: 'https://*****.firebaseio.com', projectId: '*****', storageBucket: '*****.appspot.com', messagingSenderId: '*****' }; firebase.initializeApp(firebaseConfig); // Retrieve Firebase Messaging object for background handling const messaging = firebase.messaging(); // Handle background messages (fires when app is in background/closed) messaging.setBackgroundMessageHandler(function(payload) { console.log('[sw.js] Received background message ', payload); // Optional: Customize the displayed notification const notificationTitle = 'Background Alert'; const notificationOptions = { body: payload.notification.body, icon: '/path-to-your-icon.png' }; return self.registration.showNotification(notificationTitle, notificationOptions); });
Note: Match the Firebase SDK version to what you’re using in your main app, or import via npm if you prefer—just ensure it’s the SW-compatible build.
2. Fix Webpack Configuration for Service Worker
Your Webpack setup is bundling the SW with app code, leading to MIME type issues and unstable URLs. Let’s adjust it:
Update Entry & Output
Modify your config to handle the Service Worker separately, with a stable filename (SWs need consistent URLs to update properly):
// In your entry object entry: { app: ['whatwg-fetch', './app.jsx'], sw: './sw.js' // Adjust path to your actual sw.js location in the app folder }, // In output (apply to both dev and prod configs) output: { path: path.resolve(pkg.config.buildDir), publicPath: '/', filename: DEBUG ? jsBundle : path.join('js', util.format('[name].[hash].%s.js', pkg.version)), globalObject: 'this' // Critical for SW compatibility }
3. Fix Frontend FCM Registration Code
Your frontend code has syntax and logic issues:
messagingis declared as aconstbut you try to reassign it- The SW registration path may not match the actual bundled file location
Corrected frontend code:
import * as firebase from 'firebase/app'; import 'firebase/messaging'; let messaging = null; if ('serviceWorker' in navigator) { console.log('Service worker supported!'); if (firebase.apps.length === 0) { const config = { apiKey: '***********************', authDomain: '*****.firebaseapp.com', databaseURL: 'https://*****.firebaseio.com', projectId: '*****', storageBucket: '*****.appspot.com', messagingSenderId: '*****' }; firebase.initializeApp(config); } messaging = firebase.messaging(); // Register the SW with the correct path (matches Webpack's output) navigator.serviceWorker.register('/js/sw.js') .then((registration) => { messaging.useServiceWorker(registration); // Request notification permission and retrieve FCM token messaging.requestPermission() .then(() => messaging.getToken()) .then((token) => { console.log('FCM Token:', token); // Send this token to your backend to target notifications }) .catch((err) => console.error('Permission or token error:', err)); }) .catch((err) => console.error('SW registration failed:', err)); // Handle foreground messages (app is open) messaging.onMessage((payload) => { console.log('Foreground message received:', payload); // Show a custom in-app alert if needed }); } else { console.log('Service worker not supported!'); } export default messaging;
4. Fix MIME Type & Insecure Response Errors
- MIME Type ('text/html'): This occurs when the browser tries to load
/js/sw.jsbut gets an HTML page (usually a 404). Verify your Webpack output directory has thesw.jsfile in the correctjssubfolder, and your server serves it asapplication/javascript. - ERR_INSECURE_RESPONSE: Service Workers require a secure context (HTTPS). For development:
- Use
localhost(it’s exempt from the HTTPS requirement) - If you need a custom domain, enable HTTPS in Webpack Dev Server:
// In devServer config devServer: { https: true, // ... other existing configs }
- Use
Final Checks
- Confirm the SW is registered: Open Chrome DevTools > Application > Service Workers
- Verify your Firebase project’s Web app configuration matches your code (especially
messagingSenderId) - Test notifications via the Firebase Console’s Cloud Messaging tab, targeting the FCM token logged in your browser console
内容的提问来源于stack exchange,提问作者Mirko Flyktman

