Replies: 4 comments
|
The important distinction is: copying I would verify these first: import { initializeApp } from ".../firebase/app";
import { getMessaging, isSupported } from ".../firebase/messaging";
// or, if using compat scripts, make sure both app-compat and messaging-compat are loadedand not only the app module. For self-hosting, the safer approaches are:
I would also add this diagnostic before calling console.log("messaging supported", await isSupported());If |
|
Thanks, that is very helpful. My site does not use a bundler nor framework. The service worker uses the compat version, while the host page uses an ESM to request a token via messaging. I just followed your safer approach as well as I could in this way:
I breakpointed in the ESM and SW where isSupported() is invoked and in both places it returns true. However in the ESM just after that, invoking getMessaging still encounters "Service messaging is not available". I'm testing with Chrome beta 151.0.7922.34 (Official Build) beta (x86_64) on Linux. |
|
In case it matters, the SW uses a custom filename and query parameters are appended. I append query parameters so that a PWA manifest can be generated by the SW's fetch handler, because the site provides different PWAs having different start_url's. |
|
That extra detail is useful. If In the modular SDK, I would try one of these clean setups, avoiding a mixed graph: Option A: one bundled modular page build Use a small local entry file and bundle it, then self-host the bundle: import { initializeApp } from "firebase/app";
import { getMessaging, getToken, isSupported } from "firebase/messaging";
const app = initializeApp(firebaseConfig);
if (await isSupported()) {
const messaging = getMessaging(app);
// getToken(messaging, ...)
}This is the least fragile because the bundler guarantees that app and messaging share the same dependency instance. Option B: compat everywhere for no-bundler usage If you really want script-style self-hosting, use compat consistently on both the page and the service worker: <script src="/firebase/firebase-app-compat.js"></script>
<script src="/firebase/firebase-messaging-compat.js"></script>
<script>
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
</script>and in the SW: importScripts("/firebase/firebase-app-compat.js");
importScripts("/firebase/firebase-messaging-compat.js");
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();I would avoid modular ESM on the page + compat in the service worker while debugging this. It can work in some setups, but it makes it harder to prove that both sides are using the same SDK style and version. The custom service worker filename/query params are probably not the direct cause of const registration = await navigator.serviceWorker.register("/your-sw.js?...", { scope: "/" });
await getToken(messaging, { vapidKey, serviceWorkerRegistration: registration });So my next test would be: make a tiny page that uses only compat scripts from your CDN. If compat works self-hosted, the issue is your modular ESM import graph. If compat also fails, then inspect MIME types, redirects, and whether the self-hosted files are byte-for-byte the expected browser builds. |
Uh oh!
There was an error while loading. Please reload this page.
My site is able to register for webpush and receive notifications when using the js sdk from Google's CDN, but when I self-host I consistently get "Error: Service messaging is not available". When I switch back to the CDN, everything works fine using the same browser installation (Chrome beta/Linux).
I need to self-host because some browsers like Edge/macOS block cross-site scripts by default.
I have searched issues here, the firebase Discord history, and via Gemini about self-hosting the firebase js sdk but haven't found any steps beyond those I'm already trying:
I've stepped through the invocation of the initializing of the messaging instance but I can't spot a reason for the failure. (Firebase heartbeats make this a challenge, btw.)
All reactions