Firebase is setting always default root for service worker at "/" directory
Operating System
Windows 11
Environment (if applicable)
Chrome 137.0.7151.69 (Official Build) (64-bit)
Firebase SDK Version
11.8.1
Firebase SDK Product(s)
Messaging
Project Tooling
Simple static html + js website with a default firebase service worker - nothing more nothing less
Detailed Problem Description
I was trying to fetch a token by a vapidkey from my firebase app, but getToken threw an error that it cannot find the default service worker while trying to register.
What I found is, the fact that my webpage is hosted in github pages and because of that it had default url like "github.com/app-name", is actually a problem because for "registerDefaultServiceWorker" the root is "/" ant the scope is again some constant. Basically firebase should not be setting the "/" as default place since a lot of websites can be hosted on "/some place" directory
Steps and code to reproduce issue
in html:
in initializeFirebase.js:
async function requestNotificationPermission() { const res = await Notification.requestPermission(); if (res === "denied" || res === "default") { alert("Notification access is " + res); return; }
try { const token = await messaging.getToken({ vapidKey: vapidKey, }); if (token) { console.log("🎱 Token retrieved successfully"); console.log(token); } else { requestPermission(); console.log( "No registration token available. Request permission to generate one." ); } } catch (error) { console.log("Error occured while retrieving token. "); console.error(error); } }
Locally it works, when hosted it doesn't.
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
Hi @KaloyanGG, does getToken succeed if you pass a custom service worker registration with a service worker registered at your desired path?
https://firebase.google.com/docs/reference/js/v8/firebase.messaging.Messaging#optional-serviceworkerregistration:-serviceworkerregistration
Basically this is also a problem, so no, the only way for my registration to work, and skip the default, is when I also put the "/" scope, which is not working since my webpage is not on "/" but on the "/app-name".
Basically this is also a problem, so no, the only way for my registration to work, and skip the default, is when I also put the "/" scope, which is not working since my webpage is not on "/" but on the "/app-name".
Could you please elaborate on why you aren't able to register your own service worker? I'm not sure I fully understand the issue you've described. I believe you should be able to register your own service worker at a path relative to your HTML file's path in GitHub pages.
You can try for yourself.
I cannot use my own registration by "navigatior.serviceWorker.register" because for some reason the default registration also runs. The only way that I can do it, and skip the default one, is if I give my registration a "/" scope. Which on the other hand does not work because my website on github pages is not on a "/" route but on a "/app-name" route.
You can recreate it for yourself simply with the given code example I gave you. The CDN scripts in the html and the js file to initialize firebase app, and an "initializeFirebase-server.js". I cannot show you the error because I figured out a completely different workaround which works for me but is far from the default scripts of firebase so basically I don't have the error no more. If you insist, I can return my code to the error point to copy paste you the error, but I already explained what happens
@KaloyanGG
I apologize if I'm still misunderstanding your problem. I tried to recreate your use case with the following minimal app and was able to successfully register an FCM instance:
custom-sw-path-fcm/
└── my-app
├── index.html
└── sw.js
From custom-sw-path-fcm, I run npx serve ..
Visiting http://localhost:3000/my-app, I'm able to successfully register the my-app/sw.js and get a messaging token.
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Firebase Messaging Custom Service Worker Path</title>
</head>
<body>
<script src="https://www.gstatic.com/firebasejs/11.8.1/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/11.8.1/firebase-messaging-compat.js"></script>
<script>
const app = firebase.initializeApp({
/* omitted */
});
const messaging = firebase.messaging();
function subscribe() {
if ('serviceWorker' in navigator) {
Notification.requestPermission().then(async (permission) => {
if (permission === 'granted') {
console.log('Notification permission granted');
} else {
return;
}
console.log('Registering service worker');
navigator.serviceWorker.register('./sw.js') // SW file path is relative to this file
.then((registration) => {
console.log('Getting messaging token with custom registration:', registration);
messaging.getToken(
{
vapidKey: /* omitted */,
serviceWorkerRegistration: registration // Passing our service worker registration prevents FCM from registering the default SW.
}
)
.then((currentToken) => {
console.log('currentToken:', currentToken);
})
.catch((err) => {
console.error('An error occured while retrieving token:', err);
});
})
});
}
}
</script>
<button onclick="subscribe()">Request Permissions and Get Token</button>
</body>
</html>
sw.js is just an empty file.
Yes, the problem is when hosted on github pages. Try. This problem would appear everywhere where the app is on "/some-route" as main path.
This problem would appear everywhere where the app is on "/some-route" as main path.
Does the minimal app I've shared reproduce this scenario? If not, please explain how it is different.
What is it about being hosted on GitHub Pages that causes the issue? Apps hosted on GitHub pages are hosted at the root directory.
No, it doesn't reproduce it, since you didn't mention to have hosted it in github pages. Try to do it from there.
No, it doesn't reproduce it, since you didn't mention to have hosted it in github pages. Try to do it from there.
Ok. I deployed the minimal app I have created to GitHub pages. I am still able to register the service worker and receive an FCM token.
Here's the Console output after clicking the "Request Permissions and Get Token" button in my app, in the https://dlarocque.github.io/my-app/ directory:
Notification permission granted
my-app/:31 Registering service worker
my-app/:34 Getting messaging token with custom registration: ServiceWorkerRegistration {installing: ServiceWorker, waiting: null, active: null, navigationPreload: NavigationPreloadManager, scope: 'https://dlarocque.github.io/my-app/', …}
my-app/:42 currentToken: eqgss6inellGVrMsVORpjH:APA91bFU1ZRLy1y184WPJ9y34QI1o9DsLce9eXybyWTsXGRb28Ecd77CKinSbLtsitVW_3fM4Du4LYdRqRiQ4JWHFAf7RYBeCLcIayhbMuqk0XsMa8ju_ss
Since this fully reproduces your use-case, and it behaves correctly, I believe there isn't a bug in our SDK.
In your original post, you said "firebase should not be setting the "/" as default place since a lot of websites can be hosted on "/some place" directory". This would be a disruptive breaking change that would affect all apps who rely on the service worker being registered at / by default. We will not make this change unless necessary.
I'm going to close this issue. If you still believe this is an issue in our SDK and that I have not successfully attempted to reproduce it, please open a new issue and include more detailed reproduction steps.