Ethan Leonard
Ethan Leonard

Reputation: 245

How to add a firebase-messaging-sw.js file to Bubble [EDIT - file not recognized]

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

Answers (1)

samthecodingman
samthecodingman

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

Related Questions