DEV Community

Cover image for Angular 8 + Firebase Cloud Messaging Push Notifications
Mayur Kadam
Mayur Kadam

Posted on

Angular 8 + Firebase Cloud Messaging Push Notifications

Are you looking for push notification which is normally you seen in ANDROID application or IOS application which is basically giving popup on your device notification tab when the application is closed user still received the notification. The same things can happen with your web application. In the case of the web application, you will receive the notification when the browser tab is not active and this is done by with the help of a service worker.

Now you might be wondering what is service worker ? or what is push notification ? as well so before i begin to explain it’s procedure it's better to understand some terminologies.

First, take look into what is Push Notifications

A push notification is a message popup similar to SMS. App publishers can send them at any time; users don’t have to be in the app or using their devices to receive them. They can do a lot of things; for example, they can show the latest sports scores, get a user to take any action, such as downloading a coupon or let a user know about an event, such as a flash sale.

Push notifications look like SMS text messages and mobile alerts, but they only reach users who have installed your app. Each mobile platform and browsers have support for push notifications. It gives applications the ability to receive messages pushed to them from a server, whether or not the web app is in the foreground, or even currently loaded, on a user agent.

Second, look for prerequisites of Push Notifications

as we looking push notifications in angular 8 so you must have installed Node.js version > 10. NPM will be updated also because it will be used by default. Here, I am using Node version 10.16.3 and install the latest version of Angular CLI else you can upgrade your older version into the latest CLI by command.


 install -g @angular/cli@latest

Enter fullscreen mode Exit fullscreen mode

once the project environment has been done you also require a firebase account to connect your web application into the cloud messaging.

1 ) simply visit into firebase.google.com

2 ) if you are new then click on sign up else you can log in into your old account

3) once login click into go to console tab which is in the top right corner
4) then click into Create a project

5) once the project has been created then look for its project settings General tab and create one app for getting its credentials

6 ) once your app is ready then simply copy its config for future use

Alt Text

7) also copy the server key from the Cloud Messaging tab

Alt Text

Now your all prerequisites are complete 🙂

Now Create the Angular Project

Let’s create an Angular 8 project by using the following command:


 new push-notification
   cd push-notification

Enter fullscreen mode Exit fullscreen mode

here we are using the firebase so we need to install that library so enter the following command in the same project directory.


 install firebase @angular/fire --save
   npm install firebase --save
   npm audit fix (if any vulnerabilities found else ignore)

Enter fullscreen mode Exit fullscreen mode

Now you have to create some file so follow the instruction carefully.

1) create manifest.json file save this file in the same folder where index.html file resides. We need to add a manifest.json file to our app and register it with the Angular CLI. Push Notifications use the service worker browser extension, which must be registered in this manifest.

```{

"gcm_sender_id": "YOUR-SENDER-ID"
}


then link it in the index.html file.

```<link

 rel="manifest" href="./manifest.json">

Enter fullscreen mode Exit fullscreen mode
  1. create firebase-messaging-sw.js Push messaging requires a service worker. This allows your app to detect new messages, even after the app has been closed by the user. and create this file in the same directory of manifest.json file which is in src/ directory. Note:- Before importing the below script you need to check the latest version it's better if you import the latest version of the CDN link, so here i importing 7.6.0 version links.


importScripts('https://www.gstatic.com/firebasejs/7.6.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.6.0/firebase-messaging.js');
  firebase.initializeApp({
   apiKey: “from firebase config”,
   authDomain: “from firebase config”,
   databaseURL: “from firebase config”,
   projectId: “from firebase config”,
   storageBucket: “from firebase config”,
   messagingSenderId: “from firebase config”,
   appId: “from firebase config”,
   measurementId: “from firebase config”
});
  const messaging = firebase.messaging();


Enter fullscreen mode Exit fullscreen mode
  1. we need to register these files in angular-cli.json


"assets": [
    "src/favicon.ico",
    "src/assets",
    "src/firebase-messaging-sw.js", // add this one
    "src/manifest.json" // this one also 
]


Enter fullscreen mode Exit fullscreen mode
  1. Now you have to create the service provider in my case I'm going to create a messaging service provider in the service folder which is an app directory. so move into the app directory and enter bellow command by cmd.


mkdir service
cd service
ng g s messaging


Enter fullscreen mode Exit fullscreen mode

once service has been created you have to paste below exact code into messaging.service.ts file



import { Injectable } from '@angular/core';
import { AngularFireMessaging } from '@angular/fire/messaging';
import { BehaviorSubject } from 'rxjs'
@Injectable()
export class MessagingService {
currentMessage = new BehaviorSubject(null);
constructor(private angularFireMessaging: AngularFireMessaging) {
this.angularFireMessaging.messaging.subscribe(
(_messaging) => {
_messaging.onMessage = _messaging.onMessage.bind(_messaging);
_messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
}
)
}
requestPermission() {
this.angularFireMessaging.requestToken.subscribe(
(token) => {
console.log(token);
},
(err) => {
console.error('Unable to get permission to notify.', err);
}
);
}
receiveMessage() {
this.angularFireMessaging.messages.subscribe(
(payload) => {
console.log("new message received. ", payload);
this.currentMessage.next(payload);
})
}
}


Enter fullscreen mode Exit fullscreen mode

let’s understand its functions

requestPermission(): Browser/ device will ask to user for permission to receive notification. After permission is granted by the user, firebase will return a token that can use as a reference to send a notification to the browser.

receiveMessage(): This function will be triggered when a new message has received.

  1. Update the Environment files


export const environment = {
production: false,
firebase: {
  apiKey: “from firebase config”,
  authDomain: “from firebase config”,
  databaseURL: “from firebase config”,
  projectId: “from firebase config”,
  storageBucket: “from firebase config”,
  messagingSenderId: “from firebase config”,
  appId: “from firebase config”,
  measurementId: “from firebase config”
}
};


Enter fullscreen mode Exit fullscreen mode
  1. Update the Components files

first, we will update the App Module File



import { BrowserModule } from ‘@angular/platform-browser’;
import { NgModule } from ‘@angular/core’;
import { AppRoutingModule } from ‘./app-routing.module’;
import { AppComponent } from ‘./app.component’;
import { AngularFireMessagingModule } from ‘@angular/fire/messaging’;
import { AngularFireDatabaseModule } from ‘@angular/fire/database’;
import { AngularFireAuthModule } from ‘@angular/fire/auth’;
import { AngularFireModule } from ‘@angular/fire’;
import { MessagingService } from ‘./service/messaging.service’;
import { environment } from ‘../environments/environment’;
import { AsyncPipe } from ‘../../node_modules/@angular/common’;
@NgModule({
   declarations: [AppComponent],
   imports: [
      AppRoutingModule,
      BrowserModule,
      AngularFireDatabaseModule,
      AngularFireAuthModule,
      AngularFireMessagingModule,
      AngularFireModule.initializeApp(environment.firebase),
   ],
   providers: [MessagingService,AsyncPipe],
   bootstrap: [AppComponent]
})
export class AppModule { }


Enter fullscreen mode Exit fullscreen mode

then in the HTML part, we can use pipe async and JSON



{{ message | async | json }}


Enter fullscreen mode Exit fullscreen mode

And now update the App Components file



import { Component } from ‘@angular/core’;
import { MessagingService } from ‘./service/messaging.service’;
@Component({
  selector: ‘app-root’,
  templateUrl: ‘./app.component.html’,
  styleUrls: [‘./app.component.css’]
})
export class AppComponent {
  title = ‘push-notification’;
  message;
  constructor(private messagingService: MessagingService) { }
ngOnInit() {
  this.messagingService.requestPermission()
  this.messagingService.receiveMessage()
  this.message = this.messagingService.currentMessage
 }
}


Enter fullscreen mode Exit fullscreen mode

Finally, we did the Setup process... 😉

Now run the project
run application using ng serve -o after compilation is complete, open can your browser and browser will ask for permission.

Alt Text

once you click on the allow button than it will print the token id on browser console sometime it will take time to load the token id but surely you will get that id in console dialog.

Alt Text

now we are ready to go…

Now look for sending a push notification

You can also hit Firebase Cloud Messaging directly using cURL.



curl -X POST \
  https://fcm.googleapis.com/fcm/send \
  -H 'Authorization: key=YOUR-SERVER-KEY' \
  -H 'Content-Type: application/json' \
  -d '{ 
 "notification": {
  "title": "Hey there", 
  "body": "Subscribe to mighty ghost hack youtube channel"
 },
 "to" : "YOUR-GENERATED-TOKEN"
}'


Enter fullscreen mode Exit fullscreen mode

Also, you can use the postman for sending the request i will demonstrate you by the postman

copy below JSON request and enter into the body part and also provide authorization key in the header section of postman before sending any request over googleapis and authorization key is nothing but the legacy serve key which we saw in prerequisite sections.



{
 "notification": {
 "title": "Hey there", 
 "body": "Subscribe to might ghost hack youtube channel"
 },
 "to" : "YOUR-GENERATED-TOKEN"
}


Enter fullscreen mode Exit fullscreen mode

Alt Text

once all done we can send the request to the server https://fcm.googleapis.com/fcm/send

once i click on the send button on postman i will receive the popup and one thing important you have to note down when your project is in active tab means open in browser or you are in the same tab then message will appear on HTML but it will not give you any popup until and unless you minimize it or move into another tab. when you move into another tab or minimize the browser than service worker doing his work to show you the popup message

now let me show the popup when the project tab is not in an active mode

Alt Text

now look in active mode

Alt Text

Video Tutorial

That’s it 😃

hope you get it how easily we can configure the angular project to receive the push notification.

If you want to look into the project than here is the GitHub link:- mayurkadampro/Angular-Push-Notification

Top comments (31)

Collapse
 
manishgarg0 profile image
manishgarg0

Hi I am getting below mentioned error.

Unable to get permission to notify. TypeError: Failed to execute 'subscribe' on 'PushManager': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'

Collapse
 
chaawlaapooja profile image
chaawlaapooja

I am getting the same error

Collapse
 
mayurkadampro profile image
Mayur Kadam

Check for version on firebase and also check notification permission on ur browser

Collapse
 
anthonyspault profile image
Anthony Spault

I'm facing the same issue. My firebase was previously in 7.7.0. After update to 7.8.2, still getting the error. It was working before so i'm a bit confused

Collapse
 
mayurkadampro profile image
Mayur Kadam

Check for version on firebase and also check notification permission on ur browser

Collapse
 
manishgarg0 profile image
manishgarg0

version is 7.8.1 and all the browser permissions are allowed. still, I am facing the same issue.

Collapse
 
vishtalk profile image
vishtalk

mayur bhau mala ek error yetoy yaar help kr na bhau..

ERROR in src/app/services/messaging.service.ts:10:31 - error TS2339: Property 'messaging' does not exist on type 'AngularFireMessaging'

code ->

this.angularFireMessaging.messaging.subscribe(
(_messaging) => {
_messaging.onMessage = _messaging.onMessage.bind(_messaging);
_messaging.onTokenRefresh = _messaging.onTokenRefresh.bind(_messaging);
}
)

1st line of code bg

Collapse
 
mayurkadampro profile image
Mayur Kadam

Check version of install angular fire module

Collapse
 
ppradhan9 profile image
Pradipta Pradhan

stackoverflow.com/questions/612442...
firebase version 5.1.1 is compatible

Collapse
 
prasadkhegade profile image
prasadkhegade

Hello Mayur,

Getting following error

ERROR in src/app/service/messaging.service.ts:10:35 - error TS2339: Property 'messaging' does not exist on type 'AngularFireMessaging'.

this.angularFireMessaging.messaging.subscribe(

Firebase version: 7.6.0
Angular Version: 9

Collapse
 
miqueasgutierrez profile image
miqueasgutierrez

Another simple way to integrate Push notifications in the Javascript platform is by integrating the INDIGITALL Service, it has been developed with the latest technology to guarantee maximum effectiveness and simplify the process of creating and sending Notifications with animated image, Segmented, Geolocated and many functions. .
Here you can see the steps for its integration for any Javascript platform:docs.indigitall.com/es/sdk/webpush...

Collapse
 
adibw profile image
Adib Ouechani

Hi, I have a dashboard project with angular 8 and my friend have a mobile application project with Kotlin.
I want to send a notification from my dashboard to her mobile application.
My question is how can I send the notification? Should I do the same as the tutorial?

Collapse
 
ahmedtgp profile image
Ahmed Nasser

Unable to get permission to notify. FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker for scope ('localhost:4200/firebase-cloud-mess...) with script ('localhost:4200/firebase-messaging-... A bad HTTP response code (404) was received when fetching the script. (messaging/failed-service-worker-registration).
at WindowController. (localhost:4200/firebase-messaging....)
at step (localhost:4200/vendor.js:10112:23)
at Object.throw (localhost:4200/vendor.js:10093:53)
at rejected (localhost:4200/vendor.js:10084:65)
at ZoneDelegate.invoke (localhost:4200/polyfills.js:9743:30)
at Object.onInvoke (localhost:4200/vendor.js:161262:33)
at ZoneDelegate.invoke (localhost:4200/polyfills.js:9742:36)
at Zone.run (localhost:4200/polyfills.js:9502:47)
at localhost:4200/polyfills.js:10236:40
at ZoneDelegate.invokeTask (localhost:4200/polyfills.js:9778:35)

Collapse
 
tharindu960490240 profile image
Tharindu

zone.js:699 Unhandled Promise rejection: this._next is not a function ; Zone: ; Task: ServiceWorkerContainer.addEventListener:message ; Value: TypeError: this._next is not a function
at WindowController.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next as onMessageCallback
at WindowController. (index.esm.js:1067)
at step (tslib.es6.js:100)
at Object.next (tslib.es6.js:81)
at tslib.es6.js:74
at new ZoneAwarePromise (zone.js:915)
at __awaiter (tslib.es6.js:70)
at WindowController.push../node_modules/@firebase/messaging/dist/index.esm.js.WindowController.messageEventListener (index.esm.js:1056)
at ServiceWorkerContainer. (index.esm.js:890)
at ZoneDelegate.invokeTask (zone.js:431) TypeError: this._next is not a function
at WindowController.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next as onMessageCallback
at WindowController. (localhost:4200/firebase-messaging....)
at step (localhost:4200/vendor.js:180014:23)
at Object.next (localhost:4200/vendor.js:179995:53)
at localhost:4200/vendor.js:179988:71
at new ZoneAwarePromise (localhost:4200/polyfills.js:4720:33)
at __awaiter (localhost:4200/vendor.js:179984:12)
at WindowController.push../node_modules/@firebase/messaging/dist/index.esm.js.WindowController.messageEventListener (localhost:4200/firebase-messaging....)
at ServiceWorkerContainer. (localhost:4200/firebase-messaging....)
at ZoneDelegate.invokeTask (localhost:4200/polyfills.js:4236:35)

forground error please help

"@angular/fire": "^5.4.2",
"firebase": "^7.14.2",

Collapse
 
carlossaldivia1 profile image
Carlos Saldivia

Good morning, thanks for the tutorial, it has helped me a lot in my project, however I have a question, how can I get to "get" the response of the firebase service from any page?

What happens is that my project has several pages, even though I declare the objects in the "AppComponent" as it is in your example, when I pass to another screen the service response is stopped "listening".

How could I solve this so that I am always "listening" to the service from any page of my project?

Collapse
 
mayurkadampro profile image
Mayur Kadam

right now in current market if you look for an alternative to firebase then look into aws they are also providing the same services

Collapse
 
m98 profile image
Kermani

Thanks for the good article.

Does FireBase SDK itself look for firebase-messaging-sw.js file? Don't we need to import it anywhere on page or manifest? (except importing it in Angular.json)