In a modern Angular (8+) application the service worker is generated at build time and its configuration is done via ngsw-config.json file that resides in the root folder of your project.
In your case you need to ensure your project's service worker features firebase imports and incoming notification messages handler functions. For that one strategy can be:
- create another combined-service-worker.js file
- make it import angular's service worker using importScripts('ngsw-worker.js');
- in your app.module.ts point ServiceWorkerModule to leverage combined-service-worker.js excplicitely
Here is how your combined-service-worker.js can look like:
// IMPORT ANGULAR'S SW:
importScripts('ngsw-worker.js');
// FIREBASE PART:
if (ServiceWorkerRegistration && "pushManager" in ServiceWorkerRegistration.prototype) {
importScripts('https://www.gstatic.com/firebasejs/7.13.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.13.1/firebase-messaging.js');
initializeFirebaseCloudMessaging();
const messaging = firebase.messaging();
enableBackGroundMessages();
function initializeFirebaseCloudMessaging() {
const FIREBASE_CONFIG = {
// apiKey: ...
// etc config for your firebase project
}
firebase.initializeApp(FIREBASE_CONFIG);
};
function enableBackGroundMessages() {
messaging.setBackgroundMessageHandler((payload) => {
const notificationOptions = {
body: payload.message,
icon: 'assets/img/mstile-150x150.png'
};
return self.registration.showNotification("Morphistic", notificationOptions);
});
};
};
You can create this file in your root folder and configure your project's angular.json to treat it as "asset":
"assets": [
"src/favicon.ico",
"src/robot.txt",
"src/manifest.json",
"src/combined-service-worker.js",
{
"glob": "**/*",
"input": "src/assets",
"output": "assets"
},
{
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
}
],
This will ensure the combined-service-worker.js will make it into the folder after build.
Now in your app.module.ts you can explicitly set this worker as the one app needs to activate:
...
import { ServiceWorkerModule } from '@angular/service-worker';
...
@NgModule({
declarations: [
AppComponent,
MorphBarComponent
],
imports: [
IonicModule.forRoot({
mode: 'ios'
}),
AppRoutingModule,
PipesModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule,
RouterModule,
IonicStorageModule.forRoot(),
ServiceWorkerModule.register('combined-service-worker.js', { enabled: true, registrationStrategy: 'registerImmediately' }),
BrowserModule,
HammerModule,
AngularFireModule.initializeApp(ENV.FIREBASE_CONFIG),
AngularFireMessagingModule
],
Later one when you will get hybrid builds for iOS/Android, you can tweak activation strategies such that if the Platform is 'hybrid' you skip service worker registration completely.