How to register service worker? - javascript

I can not register a service worker. The file is located along with the index.js and app.js. I get next errors
A bad HTTP response code (404) was received when fetching the script.
Failed to load resource: net::ERR_INVALID_RESPONSE
Registration failed TypeError: Failed to register a ServiceWorker: A
bad HTTP response code (404) was received when fetching the script.
******
if ('serviceWorker' in navigator) {
window.addEventListener('`load`', () => {
navigator.serviceWorker.register('serviceWorker.js', { scope:'./' })
.then((registration) => {
console.log('Registration completed successfully',registration);
})
.catch((error) => {
console.log('Registration failed', error);
})
})}

It not only have to be along side index.js and app.js, it has to be in the root of your application. so if it happens your index.js or app.js are in a folder say js, it wont work. just put serviceWorker.js in the same directory as index.html and please run it in a server
Why is this?
I am not an expert at this, but I know service workers are used to serve all your files on an offline scenerio. If you put it as a relative path, it's going to be tricky to map to all other files outside.
This is not a rule though, you can somehow find a way to put your serviceWorker in some subfolder, but I personally don't consider this a best practice

Service Workers are used to cache assets and other files so that in case of slow network or the user being offline results could be rendered on the screen. This results in better user experience.
For details you might want to visit:-
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
This is done at the index.js and if you are using latest CRA version you just need to modify the last line from serviceWorker.unregister(); to serviceWorker.register();

Related

Registering a Service Worker gives 404 in webpack project

I have a basic webpack starter project with just html, css and javascript. I am trying to register a service worker with the application but it is constantly giving 404 error in the console saying service worker not found.
A bad HTTP response code (404) was received when fetching the script.
index.js?15bb:21 Service Worker failed to install TypeError: Failed to register a ServiceWorker for scope ('http://localhost:8080/') with script ('http://localhost:8080/sw.js'): A bad HTTP response code (404) was received when fetching the script.
Can anyone help me with the issue?
I have updated my git repo which is public.
https://github.com/ankitbtanna/service-workers
Your src/sw.js is never ingested into the webpack asset pipeline, so the webpack development server doesn't know how to respond to requests for it.
If your src/sw.js is just a static file (like it is right now), then you should put it in the public/ directory, and your webpack configuration will automatically expose it to the development server.
The one wrinkle here is that you'd want to make sure that everything in public/ is served from your web root /, not from /public/, because you need the URL for your service worker to be /sw.js, not /public/sw.js.
You can change your CopyWebpackPlugin config to do this:
new CopyWebpackPlugin({
patterns: [{
from: Path.resolve(__dirname, '../public'),
to: '.', // changed from 'public'
}],
}),

FCM Push notifications works locally but not on server

I have been struggling to make push notifications work.
I am recieving the following error
; FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration).
I have already tried to google and applied https://stackoverflow.com/a/42264578/5192105
But still it works locally but not on the server.
The js file firebase-messaging-sw.js exists in the path:https://mobile-app.golocall.com/api/src/public/firebase-messaging-sw.js
I have used slim-php as backend framework.
Please help me out in resolving the error.
It tries to find the service worker file on the root of the application; hence the application tries to load
https://mobile-app.golocall.com/firebase-messaging-sw.js
while the actual file is located at
https://mobile-app.golocall.com/api/src/public/firebase-messaging-sw.js
EDIT:
You may be able to import the service worker like this:
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
If this doesn't work, you may need to declare your own service worker.
Here is a link to more information on the topic:
https://firebase.google.com/docs/cloud-messaging/js/receive

Service Worker Registration issue

Service Worker is not getting registered as I'm getting the error "a bad http response code 404 was received when fetching the script". What might be the step that I'm missing? I have registered service worker using:
<script>
if('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/ServiceWorker.js')
.then(function() { console.log("Service Worker Registered"); });
}
</script>
Also, can we cache an .aspx page in a service worker?
This script inside the page is just unable to locate /ServiceWorker.js and could be due to 1 thing out of 2. Either the file /ServiceWorker.js does not exist in your root website folder or you mistyped the name. There's no missing step at all and the snippet looks ok.
The other question is yes, you can not only cache static files like fonts, CSS and JS, but also anything dynamic network response.
Inside /ServiceWorker.js add:
self.addEventListener('fetch', function(event) {
console.log(event.request);
});
That will log in your browser console the URLs you are trying to request and you servers, images, text, etc.. and you can clone any response object and put it in your cache to be served from there on next visit.
Goog example / tutorials: https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker#serving_files_from_the_cache
Check path of your ServiceWorker.js is accessible in your file to register serviceWorker. Other hand Which file you trying to fetch, that should be inside the scope of service worker.
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/resources/ServiceWorker.js').then(function(registration) {
// Registration was successful
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function(err) {
// registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
});
}
As above snippet can fetch:
/resources/js/***.js //200 Ok
/resources/css/***.css //200 Ok
/static/***.js //404 Not found, because not in scope
Two things are possible:
Either the path/name to serviceWorker file is not correct.
ServiceWorker file is not present on the root of your folder structure.
It should be present on the root.
Using nrwl (Nx.js) you need to run nx build your_app.
It will create a public folder dist with the mockServiceWorker.js
then run : npm run msw dist
It will initialize to this folder to download stuff while service your app.

Firebase FCM React project issue - firebase-messaging-sw.js wrong type?

Im tryin to get Firebase FCM working in my React project(using webpack )
When trying to getToken() using:
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
return messaging.getToken();
})
.then(function(token) {
console.log('token')
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});
the exception is thrown as follows:
browserErrorMessage: "Failed to register a ServiceWorker: The scrip
has an unsupported MIME type ('text/html')
I understand that this issue is related to the missing service worker file: firebase-messaging-sw.js, which I added to the root of the project but I'm still getting the same error.
Im not sure what im doing wrong here, i've set up vanilla java script project and it works fine ....
Any ideas about this issue ?
For those using create-react-app, you can create the firebase-messaging-sw.js inside public folder and, on index.js add:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('../firebase-messaging-sw.js')
.then(function(registration) {
console.log('Registration successful, scope is:', registration.scope);
}).catch(function(err) {
console.log('Service worker registration failed, error:', err);
});
}
If you are using create-react-app. Add firebase-messaging-sw.js to your public folder and rebuild. firebase-messaging-sw.js can be an empty file
If you are using firebase, react and you scaffold with create react app things you need to do:
create (or move) a file in the public folder name it firebase-messaging-sw-.js
this issue is because the default route is your root folder, but since the scaffolder uses webpack you can't put the simple file in your root folder, it got to be placed in your public folder or do some config in your webpack dev server to be able to load that file from a different route
register your service worker and associate that file with firebase
you can do this in the index file (bootstrap)
Check that your service worker has been registered in your browser
for chrome you go to Devtools > Application > ServiceWorker and check yours is register
if you have any issue delete you service worker and register it again
(based on #Humble Student answer)
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('../firebase-messaging-sw.js')
.then(function(registration) {
firebase.messaging().useServiceWorker(registration);
}).catch(function(err) {
console.log('Service worker registration failed, error:', err);
});
}
Hope that helps!
In order to receive messages, you will need to create a file called firebase-messaging-sw.js. See the section Handle messages when your web app is in the foreground in the Firebase documentation:
In order to receive the onMessage event, your app must define the Firebase messaging service worker in firebase-messaging-sw.js.
The issue here was that my project setup didn't 'see' service worker file.
Since i'm using node with express, the firebase-messaging-sw.js had to be place where express is picking up static content. In my case line:
server.use(Express.static(path.join(__dirname, '../..', 'dist')));
means that I had to put firebase-messaging-sw.js into /dist folder.
I have the same exact problem as in the original question, and I have gone through all kinds of solutions without any luck over the past 3 days. I am using ReactJS and Webpack. I've tried to include file called firebase-messaging-sw.js in my root folder, but it does nothing.
Someone, please help, since the firebase notification is a much needed feature in the project I am developing...
EDIT.
I managed to solve the registration problem by installing a webpack plugin called sw-precache-webpack-plugin. This plugin autogenerates a service-worker file for you into your build directory.

404 error when trying to register serviceWorker

I get this error when trying to register the service worker:
Failed to register a ServiceWorker: A bad HTTP response code (404) was gwreceived when fetching the script.
I'm working with ionic and this is what I have in the app.js:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function(err) {
//registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
}else {
console.log('No service-worker on this browser');
}
On the directory I have the service-worker.js file right next to the app.js on the same folder.
Using latest chrome version on ubuntu desktop.
You mention that you have service-worker.js in the same directory as app.js, but the URL passed to .register() is relative to the HTML document's path. You need to make sure your service-worker.js file is in the same directory as the .html file corresponding to the page you're on.
The HTML document which is trying to register a service worker and SW.js should be in the same directory.
These are great replies and it helped with my confusion. I just wanted to add another thing just in case others are running into this problem and are confused as I was.
If you are using a bundler like Webpack, the path needs to be relative to the compiled version.
If your sw.js is in the /src folder but the compiled version of your html goes to a ./dist folder and your path to register the sw.js is "./sw.js", service worker is going to be searching in the dist folder for the sw.js file.
My solution to the problem above for Webpack is to use copy-webpack-plugin and send the file over from the src folder to the dist folder.
You just need need to pass the right path to navigator.serviceWorker.register and it doesn't necessarily need to be the same of html file.
For instance, my service-worker.js is in the Scripts folder of my app, thus I needed to pass the path "/Scripts/service-worker.js" on navigator.serviceWorker.register, like:
navigator.serviceWorker.register('/Scripts/service-worker.js')
service workers and index.html file should be in a common directory.
This Problem is Caused By the sw.js file position in your directory
Possible Solution -
Move your sw.js file out of any sub folder/directory and put it at the common or public folder. And the error would go away and the Service Worker would get easily registered.
Try to set the source to look in the root directory using a ~
Like this:
navigator.serviceWorker.register('~service-worker.js')

Categories

Resources