我正在尝试订阅用户,但这是我第一次收到错误。 第二次,它可以工作,因为用户已经处于活动状态
这是我的代码:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('sw.js').then(function(reg) {
console.log(':^)', reg);
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
var div = document.getElementById('id');
div.innerHTML = div.innerHTML + sub.endpoint;
// var b = document.getElementsByTagName('body')[0];
//b.appendChild(div);
//alert(sub.endpoint);
});
});
}
我已经尝试过以下方法,但是
ready.then()
方法没有发生:
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('sw.js').then(function(sreg) {
console.log(':^)', sreg);
navigator.serviceWorker.ready.then(function(reg) {
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
var div = document.getElementById('id');
div.innerHTML = div.innerHTML + sub.endpoint;
// var b = document.getElementsByTagName('body')[0];
//b.appendChild(div);
//alert(sub.endpoint);
});
});
});
}
有什么想法吗?
您应该等待 Service Worker 被激活后再触发订阅。
使用 stateChange 侦听器来确定 Service Worker 是否处于活动状态
navigator.serviceWorker.register(workerFileName, {scope: "/"})
.then(
function (reg) {
var serviceWorker;
if (reg.installing) {
serviceWorker = reg.installing;
// console.log('Service worker installing');
} else if (reg.waiting) {
serviceWorker = reg.waiting;
// console.log('Service worker installed & waiting');
} else if (reg.active) {
serviceWorker = reg.active;
// console.log('Service worker active');
}
if (serviceWorker) {
console.log("sw current state", serviceWorker.state);
if (serviceWorker.state == "activated") {
//If push subscription wasnt done yet have to do here
console.log("sw already activated - Do watever needed here");
}
serviceWorker.addEventListener("statechange", function(e) {
console.log("sw statechange : ", e.target.state);
if (e.target.state == "activated") {
// use pushManger for subscribing here.
console.log("Just now activated. now we can subscribe for push notification")
subscribeForPushNotification(reg);
}
});
}
},
function (err) {
console.error('unsuccessful registration with ', workerFileName, err);
}
);
您可以通过检查 Service Worker 状态来解决此问题。仅当 Service Worker 处于活动状态时才执行您的操作。
navigator.serviceWorker.register('sw.js').then(function(reg) {
if(reg.installing) {
console.log('Service worker installing');
} else if(reg.waiting) {
console.log('Service worker installed');
} else if(reg.active) {
console.log('Service worker active');
}
// Include below mentioned validations
}
检查是否支持推送通知
// Check if push messaging is supported
if (!('PushManager' in window)) {
console.log('Push messaging isn\'t supported.');
return;
}
//
if (Notification.permission === 'denied') {
console.log('The user has blocked notifications.');
return;
}
这两项检查后即可实现您的功能。
navigator.serviceWorker.ready.then(function(reg) { .... })
希望这有帮助
在我的场景中,我遇到了类似的问题,第一次尝试订阅推送通知时出现错误
Subscription failed - no active Service Worker
。发生这种情况是因为 Service Worker 尚未完全激活。第二次尝试成功了,因为 Service Worker 已经处于活动状态。
以下是调整代码来解决此问题的方法:
等待 Service Worker 准备就绪: 为了确保 Service Worker 在订阅之前完全激活,您应该等待 Service Worker 准备好。
实施步骤:
firebase-messaging-sw.js
(确保您的应用正确注册并使用此文件):
importScripts("https://www.gstatic.com/firebasejs/9.22.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/9.22.0/firebase-messaging-compat.js");
const firebaseConfig = {
/* Your config */
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
self.addEventListener("install", (event) => {
console.log("Service worker installed");
});
self.addEventListener("activate", (event) => {
console.log("Service worker activated");
});
messaging-init-sw.js
(初始化Firebase并请求权限的主文件):
import { initializeApp } from "firebase/app";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
const firebaseConfig = {
/* Your config */
};
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
export async function requestPermission(callback) {
try {
const permission = await Notification.requestPermission();
if (permission === "granted") {
if ("serviceWorker" in navigator) {
try {
// Register the Service Worker
const registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js');
// Wait for the Service Worker to be ready
await navigator.serviceWorker.ready;
// Perform your custom actions here
// For example, getting a device token:
// const deviceToken = await getToken(messaging, {
// vapidKey: "YOUR_VAPID_KEY",
// serviceWorkerRegistration: registration,
// });
// if (deviceToken) {
// callback(deviceToken);
// } else {
// console.log("No registration token available.");
// }
// Replace the above with your own logic
} catch (error) {
console.error("Error setting up Service Worker or getting token:", error);
}
} else {
console.log("Service workers are not supported in this browser.");
}
} else {
console.log("Unable to get permission to notify.");
}
} catch (error) {
console.error("An error occurred while requesting permission:", error);
}
}
Login.vue
(初始化Firebase并请求权限的主文件):
<script>
import { getMessaging, isSupported } from "firebase/messaging";
export default {
name: "YourComponent",
async mounted() {
try {
if (await isSupported()) {
const messaging = getMessaging();
console.log("Firebase Messaging is supported and initialized.");
} else {
console.warn("Firebase Messaging is not supported in this browser.");
}
} catch (error) {
console.error("Error initializing Firebase Messaging:", error);
}
},
};
</script>
说明:
navigator.serviceWorker.ready
等待其准备就绪。.catch
块处理过程中可能发生的错误。通过实施这些更改,您可以确保 Service Worker 在订阅之前已完全准备好,这应该可以解决您遇到的错误。