Reputation: 245
I know that in a common resolution to the error below, I need to add a firebase-messaging-sw.js file. Since I'm using a bubble HTML element to run the script, I'm not sure how to do that. I tried using a CDN, but I'm not sure I did it properly, or if there is a better way. What do you think?
Here's the error:
An error occurred while retrieving token. FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: The document is in an invalid state. (messaging/failed-service-worker-registration).
at registerDefaultSw (registerDefaultSw.ts:43:25)
at async updateSwReg (updateSwReg.ts:28:5)
at async getToken$1 (getToken.ts:43:3)
An error occurred while retrieving token. FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: The document is in an invalid state. (messaging/failed-service-worker-registration).
Here's how I tried to add the file:
<script type="importmap">
{
"imports": {
"firebase/app": "https://www.gstatic.com/firebasejs/9.6.9/firebase-app.js",
"firebase/messaging" :"https://www.gstatic.com/firebasejs/9.6.9/firebase-messaging.js"
}
}
</script>
<script type="module">
import { initializeApp } from 'firebase/app';
import { getMessaging,getToken } from "firebase/messaging";
const firebaseConfig = {
//my config
}
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
const swUrl = 'https://3b4293b7c2497062d0307b62bd49f75f.cdn.bubble.io/f1720473376600x761326990998907800/firebase-messaging-sw.js';
const sw = document.createElement('script');
sw.src = swUrl;
document.head.appendChild(sw);
getToken(messaging, {vapidKey: '...myactualvapidkey...'}).then((currentToken) => {
if (currentToken) {
console.log(currentToken);
} else {
console.log('No registration token available. Request permission to generate one.');
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
});
</script>
Note that the service worker file is currently empty, because according to this tutorial, it should work with an empty file.
I also tried the answer from this similar question, but it didn't work for me. I got an import issue when trying to use the 'firebase/messaging/sw' package.
EDIT
I've discovered that it is possible to add a file to root (at the way end of Settings-->SEO/metatags) , but the file doesn't seem to be recognized. I've tried the following to get the service worker to be recognized:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/firebase-messaging-sw.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}
but I get this error:
ServiceWorker registration failed: DOMException: Failed to register a ServiceWorker: The document is in an invalid state.
Note that this code is being rendered from an iFrame and that the file firebase-messaging-sw.js
is empty.
Upvotes: 0
Views: 468
Reputation: 26171
Note: This answer is a work in progress and/or incomplete. I am sharing what I have in case it helps someone else investigating this.
<script type="module">
(async function () {
// note: targetting Firebase Web SDK v10.12.3
// note: using direct import() syntax just for testing
const { initializeApp } = await import("https://www.gstatic.com/firebasejs/10.12.3/firebase-app.js");
const { getMessaging, getToken } = await import("https://www.gstatic.com/firebasejs/10.12.3/firebase-messaging.js");
const firebaseConfig = {
// my config
}
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
const serviceWorkerRegistration = await window.navigator.serviceWorker.register(
(location.pathname.startsWith("/version-test") ? "/version-test" : "") + "/firebase-messaging-sw.js",
{
scope: "/firebase-cloud-messaging-push-scope"
}
);
// note: deleted lines where service worker was attached as a script
try {
const currentToken = await getToken(messaging, {
vapidKey: "<VAPID_KEY>",
serviceWorkerRegistration
});
if (currentToken) {
console.log(currentToken);
} else {
console.warn('No registration token available. Request permission to generate one.');
}
} catch (err) {
console.error('An error occurred while retrieving token. ', err);
}
})()
.catch(err => console.error("An unexpected error occurred.", err));
</script>
Note: "/firebase-cloud-messaging-push-scope"
is the default scope value used by the SDK
Upvotes: 1