Push Notifications with Angular & Express

Adding the service worker module

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ng add @angular/pwa
ng add @angular/pwa
ng add @angular/pwa

Generating a VAPID key-pair

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
yarn global add web-push
yarn global add web-push
yarn global add web-push
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
web-push generate-vapid-keys --json
web-push generate-vapid-keys --json
web-push generate-vapid-keys --json

Subscribing to push notifications

src/app/app.component.ts

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Component } from '@angular/core'
import { SwPush } from '@angular/service-worker'
import { PushNotificationService } from './pushNotification.service'
const VAPID_PUBLIC =
'BNOJyTgwrEwK9lbetRcougxkRgLpPs1DX0YCfA5ZzXu4z9p_Et5EnvMja7MGfCqyFCY4FnFnJVICM4bMUcnrxWg'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
class AppComponent {
title = 'angular-push-notifications'
constructor(swPush: SwPush, pushService: PushNotificationService) {
if (swPush.isEnabled) {
swPush
.requestSubscription({
serverPublicKey: VAPID_PUBLIC,
})
.then(subscription => {
pushService.sendSubscriptionToTheServer(subscription).subscribe()
})
.catch(console.error)
}
}
}
import { Component } from '@angular/core' import { SwPush } from '@angular/service-worker' import { PushNotificationService } from './pushNotification.service' const VAPID_PUBLIC = 'BNOJyTgwrEwK9lbetRcougxkRgLpPs1DX0YCfA5ZzXu4z9p_Et5EnvMja7MGfCqyFCY4FnFnJVICM4bMUcnrxWg' @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) class AppComponent { title = 'angular-push-notifications' constructor(swPush: SwPush, pushService: PushNotificationService) { if (swPush.isEnabled) { swPush .requestSubscription({ serverPublicKey: VAPID_PUBLIC, }) .then(subscription => { pushService.sendSubscriptionToTheServer(subscription).subscribe() }) .catch(console.error) } } }
import { Component } from '@angular/core'
import { SwPush } from '@angular/service-worker'
import { PushNotificationService } from './pushNotification.service'

const VAPID_PUBLIC =
  'BNOJyTgwrEwK9lbetRcougxkRgLpPs1DX0YCfA5ZzXu4z9p_Et5EnvMja7MGfCqyFCY4FnFnJVICM4bMUcnrxWg'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
class AppComponent {
  title = 'angular-push-notifications'

  constructor(swPush: SwPush, pushService: PushNotificationService) {
    if (swPush.isEnabled) {
      swPush
        .requestSubscription({
          serverPublicKey: VAPID_PUBLIC,
        })
        .then(subscription => {
          pushService.sendSubscriptionToTheServer(subscription).subscribe()
        })
        .catch(console.error)
    }
  }
}

src/app/pushNotification.service.ts

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'
const SERVER_URL = 'http://localhost:3000/subscription'
@Injectable()
class PushNotificationService {
constructor(private http: HttpClient) {}
public sendSubscriptionToTheServer(subscription: PushSubscription) {
return this.http.post(SERVER_URL, subscription)
}
}
import { Injectable } from '@angular/core' import { HttpClient } from '@angular/common/http' const SERVER_URL = 'http://localhost:3000/subscription' @Injectable() class PushNotificationService { constructor(private http: HttpClient) {} public sendSubscriptionToTheServer(subscription: PushSubscription) { return this.http.post(SERVER_URL, subscription) } }
import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http'

const SERVER_URL = 'http://localhost:3000/subscription'

@Injectable()
class PushNotificationService {
  constructor(private http: HttpClient) {}

  public sendSubscriptionToTheServer(subscription: PushSubscription) {
    return this.http.post(SERVER_URL, subscription)
  }
}

Setting up a new Express project

Installing dependencies

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
yarn add body-parser cors express web-push
yarn add body-parser cors express web-push
yarn add body-parser cors express web-push

Creating an Express server

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const express = require('express')
const webpush = require('web-push')
const cors = require('cors')
const bodyParser = require('body-parser')
const PUBLIC_VAPID =
'BNOJyTgwrEwK9lbetRcougxkRgLpPs1DX0YCfA5ZzXu4z9p_Et5EnvMja7MGfCqyFCY4FnFnJVICM4bMUcnrxWg'
const PRIVATE_VAPID = '_kRzHiscHBIGftfA7IehH9EA3RvBl8SBYhXBAMz6GrI'
const fakeDatabase = []
const app = express()
app.use(cors())
app.use(bodyParser.json())
webpush.setVapidDetails('mailto:you@domain.com', PUBLIC_VAPID, PRIVATE_VAPID)
app.post('/subscription', (req, res) => {
const subscription = req.body
fakeDatabase.push(subscription)
})
app.post('/sendNotification', (req, res) => {
const notificationPayload = {
notification: {
title: 'New Notification',
body: 'This is the body of the notification',
icon: 'assets/icons/icon-512x512.png',
},
}
const promises = []
fakeDatabase.forEach(subscription => {
promises.push(
webpush.sendNotification(
subscription,
JSON.stringify(notificationPayload)
)
)
})
Promise.all(promises).then(() => res.sendStatus(200))
})
app.listen(3000, () => {
console.log('Server started on port 3000')
})
const express = require('express') const webpush = require('web-push') const cors = require('cors') const bodyParser = require('body-parser') const PUBLIC_VAPID = 'BNOJyTgwrEwK9lbetRcougxkRgLpPs1DX0YCfA5ZzXu4z9p_Et5EnvMja7MGfCqyFCY4FnFnJVICM4bMUcnrxWg' const PRIVATE_VAPID = '_kRzHiscHBIGftfA7IehH9EA3RvBl8SBYhXBAMz6GrI' const fakeDatabase = [] const app = express() app.use(cors()) app.use(bodyParser.json()) webpush.setVapidDetails('mailto:you@domain.com', PUBLIC_VAPID, PRIVATE_VAPID) app.post('/subscription', (req, res) => { const subscription = req.body fakeDatabase.push(subscription) }) app.post('/sendNotification', (req, res) => { const notificationPayload = { notification: { title: 'New Notification', body: 'This is the body of the notification', icon: 'assets/icons/icon-512x512.png', }, } const promises = [] fakeDatabase.forEach(subscription => { promises.push( webpush.sendNotification( subscription, JSON.stringify(notificationPayload) ) ) }) Promise.all(promises).then(() => res.sendStatus(200)) }) app.listen(3000, () => { console.log('Server started on port 3000') })
const express = require('express')
const webpush = require('web-push')
const cors = require('cors')
const bodyParser = require('body-parser')

const PUBLIC_VAPID =
  'BNOJyTgwrEwK9lbetRcougxkRgLpPs1DX0YCfA5ZzXu4z9p_Et5EnvMja7MGfCqyFCY4FnFnJVICM4bMUcnrxWg'
const PRIVATE_VAPID = '_kRzHiscHBIGftfA7IehH9EA3RvBl8SBYhXBAMz6GrI'

const fakeDatabase = []

const app = express()

app.use(cors())
app.use(bodyParser.json())

webpush.setVapidDetails('mailto:you@domain.com', PUBLIC_VAPID, PRIVATE_VAPID)

app.post('/subscription', (req, res) => {
  const subscription = req.body
  fakeDatabase.push(subscription)
})

app.post('/sendNotification', (req, res) => {
  const notificationPayload = {
    notification: {
      title: 'New Notification',
      body: 'This is the body of the notification',
      icon: 'assets/icons/icon-512x512.png',
    },
  }

  const promises = []
  fakeDatabase.forEach(subscription => {
    promises.push(
      webpush.sendNotification(
        subscription,
        JSON.stringify(notificationPayload)
      )
    )
  })
  Promise.all(promises).then(() => res.sendStatus(200))
})

app.listen(3000, () => {
  console.log('Server started on port 3000')
})

References
https://malcoded.com/posts/angular-push-notifications/
https://blog.angular-university.io/angular-push-notifications/
https://medium.com/@a.adendrata/push-notifications-with-angular-6-firebase-cloud-massaging-dbfb5fbc0eeb
https://developers.google.com/web/fundamentals/push-notifications/display-a-notification