Firebase报错:messaging.onBackgroundMessage不是函数的问题排查
FCM onBackgroundMessage报错及消息打印实现方案
问题描述
执行以下FCM代码时,能正常生成推送token,但抛出错误:
Uncaught TypeError: messaging.onBackgroundMessage is not a function
at firebase.js:31:11
用户提供的代码:
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.16.0/firebase-app.js"; import { getMessaging, getToken } from "https://www.gstatic.com/firebasejs/9.16.0/firebase-messaging.js"; //This data is filled correctly just clearing it here for the question const firebaseConfig = { apiKey: "", authDomain: "", projectId: "t", storageBucket: "", messagingSenderId: "", appId: "", measurementId: "" }; // Initialize Firebase const bbFirebase = initializeApp(firebaseConfig); const messaging = getMessaging(); // Add the public key generated from the console here. getToken(messaging, { vapidKey: 'I_HAVE_PLACED_VALID_KEY_HERE' }).then((currentToken) => { if (currentToken) { console.log("TOKEN: " + currentToken); } else { // Show permission request UI console.log('No registration token available. Request permission to generate one.'); // ... } }).catch((err) => { console.log('An error occurred while retrieving token. ', err); // ... }); messaging.onBackgroundMessage((payload) => { console.log('[firebase-messaging-sw.js] Received background message ', payload); // Customize notification here const notificationTitle = payload.notification.title; const notificationOptions = { body: payload.notification.body, icon: '/firebase-logo.png' }; self.registration.showNotification(notificationTitle, notificationOptions); }); function requestPermission() { console.log('Requesting permission...'); Notification.requestPermission().then((permission) => { if (permission === 'granted') { console.log('Notification permission granted.'); // TODO(developer): Retrieve a registration token for use with FCM. // In many cases once an app has been granted notification permission, // it should update its UI reflecting this. resetUI(); } else { console.log('Unable to get permission to notify.'); } }); }
错误原因
- API未导入:
onBackgroundMessage方法没有从firebase-messaging.js中导入,当前仅导入了getMessaging和getToken。 - 使用场景错误:
onBackgroundMessage是专门给Service Worker(后台服务线程)用的方法,不能直接在主页面脚本里调用。主页面处理前台消息要用onMessage,后台消息逻辑必须放在单独的Service Worker文件中。
解决方法与消息打印实现
1. 处理前台消息(页面活跃时)
修改主页面脚本,补充导入onMessage并替换错误的监听逻辑:
// 补充导入onMessage方法 import { getMessaging, getToken, onMessage } from "https://www.gstatic.com/firebasejs/9.16.0/firebase-messaging.js"; // ... 原有初始化、获取token的代码保持不变 ... // 监听前台消息,页面打开时触发,直接打印到控制台 onMessage(messaging, (payload) => { console.log('[前台收到消息]', payload); // 可在此添加自定义的前台消息展示逻辑 });
2. 处理后台消息(页面后台/关闭时)
创建单独的firebase-messaging-sw.js文件(放在项目根目录),写入以下代码:
importScripts('https://www.gstatic.com/firebasejs/9.16.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/9.16.0/firebase-messaging.js'); // 填入你的Firebase配置 const firebaseConfig = { apiKey: "", authDomain: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "", measurementId: "" }; firebase.initializeApp(firebaseConfig); const messaging = firebase.messaging(); // 后台消息监听,日志需在浏览器Application > Service Workers面板查看 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
在主页面脚本中添加Service Worker注册逻辑,确保后台消息能被处理:
// 注册Service Worker if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/firebase-messaging-sw.js') .then(reg => console.log('Service Worker注册成功:', reg.scope)) .catch(err => console.log('Service Worker注册失败:', err)); }); }
注意事项
- 前台消息的日志直接在浏览器控制台可见;后台消息的日志需要打开浏览器的Application > Service Workers面板,选中对应的Service Worker后查看其控制台。
- 确保Firebase配置信息在主页面和Service Worker文件中都正确填写。
内容的提问来源于stack exchange,提问作者Venelin
相关产品推荐
相关产品推荐

