How can we use FCM Service Worker with a existing Service Worker?

11,728

Solution 1

In order to take all control of sw.js and push notification useServiceWorker is very useful.

See this documentation useServiceWorker(registration)

   /------index.html------/
    var config = {
        apiKey: "xxxxxxxxxxxx",
        authDomain: "xxxxxxxxxxxx",
        databaseURL: "xxxxxxxxxxxx",
        projectId: "xxxxxxxxxxxx",
        storageBucket: "xxxxxxxxxxxx",
        messagingSenderId: "xxxxxxxxxxxx"
    };
    firebase.initializeApp(config);
    var messaging = firebase.messaging();

navigator.serviceWorker.register('service-worker.js')
.then((registration) => {
  messaging.useServiceWorker(registration);


});

Solution 2

In app.module.ts or you can put the snippet starting with constructor(sw...) into a service file that you will initialise when it reaches certain lazy loaded feature module.

import * as firebase from 'firebase';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ServiceWorkerModule.register('/ngsw-worker.js', {enabled: environment.production}),
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(swPush: SwPush) {
    if (swPush.isEnabled) {
      navigator.serviceWorker
        .ready
        .then((registration) => firebase.messaging().useServiceWorker(registration));
    }
  }
}

In angular-cli.json make sure you have firebase-messaging-sw.js

{
  "apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico",
        "manifest.json",
        "firebase-messaging-sw.js"
      ],
      "index": "index.html",
      "main": "main.ts",
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      },
      "serviceWorker": true
    }
  ]
}
Share:
11,728
Pranav C Balan
Author by

Pranav C Balan

jquery, javascript, html, css, arrays, regex GITHUB :   pranavcbalan   pranavxc LinkedIn Facebook Twitter Mail Id : [email protected]__ Loves to solve problems, learn new things and help others.

Updated on June 28, 2022

Comments

  • Pranav C Balan
    Pranav C Balan almost 2 years

    We are creating a PWA web app and currently, we are using sw-precache library for generating service worker file, which is working as expected. And now we have added FCM service worker for listening incoming message while it's offline, but it's overwriting our existing service worker.

    So how can we integrate the firebase service worker with an existing service worker which is generated using sw-precache?

    I'd tried several ways, current code :

    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('/service-worker.js').then((registration) => {
            console.log('Service Worker registered');
        }).catch(function (err) {
            console.log('Service Worker registration failed: ', err);
        });
    
        navigator.serviceWorker.register('/firebase-messaging-sw.js', { scope: '/firebase-cloud-messaging-push-scope' }).then(function (registration) {
             console.log('f Service Worker registered');
         }).catch(function (err) {
             console.log('f Service Worker registration failed: ', err);
         });
    }
    

    UPDATE 1: I'd tried useServiceWorker(registration) as well, its registering the main service worker but when I'd initializing firebase within my service it's expecting the firebase-messaging-sw.js to load so it's throwing some error in console.

    Service code:

    import * as firebase from 'firebase';
    import { isPlatformBrowser } from '@angular/common';
    
    @Injectable()
    export class MessagingService {   
      messaging;
    
      constructor(
        @Inject(PLATFORM_ID) private _platformId: Object, ) {
        if (isPlatformBrowser(this._platformId)) {
          var config = {
            messagingSenderId: "XXXXXXXX"
          };
    
          firebase.initializeApp(config);
          this.messaging = firebase.messaging();
        }
      }
    
      //  ......
    
    }
    

    Error in console :

    enter image description here

    enter image description here

    Tried the following answer as well, but no success: https://stackoverflow.com/a/46171748/3037257


    UPDATE 2: Finally adding useServiceWorker(registration) and an empty firebase-messaging-sw.js file both service workers are getting registered but caching is not working.
    • haripcce
      haripcce over 3 years
      /service-worker.js the provided path is incorrect. I have provided path as ${process.env.PUBLIC_URL}/firebase-messaging-sw.js with firebase-messaging-sw.js in public folder of create react application.
  • Pranav C Balan
    Pranav C Balan over 6 years
    I'd tried this one as well.... but when i'd tried to initialize firebase within my service.... it's showing service worker registartion failed.....
  • Tushar Acharekar
    Tushar Acharekar over 6 years
    1st, SW dont have access to your dom, so if you want to initialize firebase in SW then you should import all firebase dependency at starting of SW. 2nd you no need to initialize firebase in SW, write above code in index.html.
  • Tushar Acharekar
    Tushar Acharekar over 6 years
    Can you share screenshot of your file structure in project directory...!
  • Pranav C Balan
    Pranav C Balan over 6 years
    in production both service-worker would be in same directory, /dist folder
  • Tushar Acharekar
    Tushar Acharekar over 6 years
    firebase-messaging-sw.js is mandatory file for FCM push notification, i think your problem root is mime-type text/html, try to remove that error
  • Pranav C Balan
    Pranav C Balan over 6 years
    I'd removed firebase-messaging-sw.js file since messaging.useServiceWorker(registration); is added
  • Pranav C Balan
    Pranav C Balan over 6 years
    also what would be the content?
  • Pranav C Balan
    Pranav C Balan over 6 years
    both service workers are getting registered but caching is not working
  • Tushar Acharekar
    Tushar Acharekar over 6 years
    Are you aware about, SW only register on localhost or https...?
  • Pranav C Balan
    Pranav C Balan over 6 years
  • Nuria Ruiz
    Nuria Ruiz almost 6 years
    I cannot see your discussion in chat. How did you solve that problem? I'm in the same situation except that I have a polymer project that generates the service-worker.js in build time and I need to integrate firebase-messaging-sw.js.
  • izio
    izio over 4 years
    Same here, but i'm developing a PWA with react. Can you provide some more infos?