我想在我的 nextjs 项目中实现 firebase 推送通知。问题是我在页面最初加载时遇到此错误
An error occurred while retrieving token. DOMException: Failed to execute 'subscribe' on 'PushManager': Subscription failed - no active Service Worker
at getPushSubscription (webpack-internal:///(app-pages-browser)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:581:39)
at async getTokenInternal (webpack-internal:///(app-pages-browser)/./node_modules/@firebase/messaging/dist/esm/index.esm2017.js:496:30
也没有获取令牌,但是当我重新加载页面时,它正在工作并获取令牌。如何解决这个问题呢?我在公共目录中添加了 firebase-messaging-sw.js 和我的 firebase npm 版本“firebase”:“^10.7.1”,
这是我的 firebase-messaging-sw.js 代码:
importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.10.1/firebase-messaging.js');
firebase.initializeApp({
my configration
});
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
// Customize notification here
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: '/firebase-logo.png'
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
当绑定从另一个 js 文件导入模型时,也会看到 firebase-messaging-sw.js 文件的此错误
Uncaught SyntaxError: Cannot use import statement outside a module
// 1. Import scripts in firebase-messaging-sw.js with compact-script
// e.g.,
// importScripts('https://www.gstatic.com/firebasejs/x.x.x/firebase-app-compat.js');
// importScripts('https://www.gstatic.com/firebasejs/x.x.x/firebase-messaging-compat.js');
// 2. Register firebase-messaging-sw.js with scope '/firebase-cloud-messaging-push-scope' in _app.js
// inside the useEffect
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
// Register the service worker as soon as the app loads
navigator.serviceWorker
.register('/firebase-messaging-sw.js', { scope: '/firebase-cloud-messaging-push-scope' })
.then((registration) => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch((err) => {
console.log('Service worker registration failed, error:', err);
});
});
}
// 3. Create a function to ask for notification permission or modify this function
import { getMessaging, getToken } from 'firebase/messaging';
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
apiKey: "",
authDomain: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: "",
measurementId: ""
};
// Initialize Firebase
export const firebaseApp = initializeApp(firebaseConfig);
export const askUserForNotificationPermission = async () => {
if (typeof window !== 'undefined' && 'serviceWorker' in navigator) {
const messaging = getMessaging(firebaseApp);
const permission = await Notification.requestPermission();
if (permission === "granted") {
const currentToken = await getToken(messaging, {
vapidKey: PUBLIC_VAPID_KEY
});
if (currentToken) {
console.log(":::currentToken", currentToken);
} else {
console.log('No registration token available. Request permission to generate one.');
}
} else {
console.warn("Notification permission DENIED");
}
}
}