web-dev-qa-db-fra.com

Angular 7 pwa/SwPush - Les notifications push ne fonctionnent pas

J'essaie de faire fonctionner les notifications Push dans Angular 7 en utilisant @ angular/pwa link et en utilisant SwPush. Je ne parviens pas à obtenir de notifications push réelles. Je travaille actuellement sur localhost (en exécutant http-server après avoir effectué une construction ng) et mon serveur api est situé dans le cloud . J'ai pu activer le abonnement avec swPush.requestSubscription et l'abonnement est enregistré avec succès sur le serveur . Dans Chrome, tous les appels d'api sont bloqués à partir du service worker lui-même (échec: de service Worker), tandis le message n'apparaît pas.

J'ai ajouté les extraits de code pertinents ci-dessous. Puisqu'aucune erreur spécifique n'a été signalée, je ne peux pas continuer. 

S'il vous plaît conseiller sur la façon de faire ce travail et d'afficher des notifications.

app.module.ts

import {PushNotificationService} from 'core';
import { ServiceWorkerModule } from '@angular/service-worker';
@NgModule({
declarations: [
    AppComponent,

],
imports: [

    ServiceWorkerModule.register('ngsw-worker.js', { enabled: true })
],
providers: [
    PushNotificationService,
],
exports: [],
bootstrap: [AppComponent]
   })
 export class AppModule {
  }


   app.component.ts
export class AppComponent  {

constructor(private pushNotification :PushNotificationService,
private swPush : SwPush){
this.swPush.messages.subscribe(notification => {
          const notificationData: any = notification;
     const options = {
      body: notificationData.message,
      badgeUrl: notificationData.badgeUrl,
      icon: notificationData.iconUrl
    };
    navigator.serviceWorker.getRegistration().then(reg => {
      console.log('showed notification');
      reg.showNotification(notificationData.title, options).then(res => {
        console.log(res);
      }, err => {
        console.error(err);
      });
    });
  });

}
     isSupported() {
      return this.pushNotification.isSupported;
   }

  isSubscribed() {
  console.log(' ****** profile component' + this.swPush.isEnabled);
  return this.swPush.isEnabled;
}

 enablePushMessages() {
  console.log('Enable called'); 
  this.pushNotification.subscribeToPush();

}

 disablePushMessages(){
  // code for unsubsribe
  }
}

Push.notification.service

 export class PushNotificationService {
 public isSupported = true;
 public isSubscribed = false;
 private swRegistration: any = null;
  private userAgent = window.navigator.userAgent;
 constructor(private http: HttpClient, private swPush: SwPush) {
   if ((this.userAgent.indexOf('Edge') > -1) || 
   (this.userAgent.indexOf('MSIE') > -1) || (this.userAgent.indexOf('.Net') 
    > -1)) {
      this.isSupported = false;
    }
}

subscribeToPush() {
// Requesting messaging service to subscribe current client (browser)
  let publickey = 'xchbjhbidcidd'
   this.swPush.requestSubscription({
    serverPublicKey: publickey
   }).then(pushSubscription => {
     console.log('request Push subscription ', pushSubscription);
     this.createSubscriptionOnServer(pushSubscription);
      })
  .catch(err => {
    console.error(err);
  });
}

 createSubscriptionOnServer(subscription) {
  let urlName = 'api/user/notificationSubscription';
  let params;
  params = {
  endpoint: subscription.endpoint,
   };
this.http.put<any>(urlName, params, httpOptions).pipe(
  tap((res) => {
    if (res.data) {
      if (res.data.success) {
        alert('Success')
      } else {
        alert('error')
      }
    }
  }));
 }
 }
5
ramya krishna

pour que le service-worker fonctionne, vous devez compiler avec --prod .

1
daniel

Vous devez installer Angular CLI, PWA pour le technicien, Webpush pour générer des clés VAPID et un serveur http pour exécuter un serveur fictif. Vous pouvez le faire en lançant: 

npm i -g @angular/cli --save
ng add @angular/pwa --save
npm i webpush --save
npm i http-server -g --save

Maintenant, vous devez générer une paire de clés VAPID à l'aide de webpush pour pouvoir l'utiliser en amont et en aval.

web-Push generate-vapid-keys --json

Enregistrez la paire générée quelque part. Utilisez le code ci-dessous dans app.component.ts pour demander un abonnement à l'utilisateur.

import { Component } from '@angular/core';
import { SwPush } from '@angular/service-worker';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(swPush: SwPush) {
if (swPush.isEnabled) {
  swPush.requestSubscription({
      serverPublicKey: VAPID_PUBLIC_KEY
    })
    .then(subscription => {
      // send subscription to the server
    })
    .catch(console.error);
}
  }
}

VAPID_PUBLIC_KEY est la clé publique que vous avez obtenue précédemment. 

Ajoutez-le à votre projet angulaire dans le noeud node_modules/@angular/service-worker/ngsw-worker.js

this.scope.addEventListener('notificationclick', (event) => {
            console.log('[Service Worker] Notification click Received. event:%s', event);
            event.notification.close();
            if (clients.openWindow && event.notification.data.url) {
                event.waitUntil(clients.openWindow(event.notification.data.url));
            }
        });

Vous pouvez entrer le code ci-dessus où vous trouvez la ligne ci-dessous à l'intérieur du fichier> ce serait dans la ligne numéro 1893.

this.scope.addEventListener('notificationclick', (event) => ..

Et vous devez reconstruire la dist pour que cela fonctionne . Maintenant, utilisez 

ng build --prod

pour générer le dist et le servir en utilisant

http-server ./dist/YOUR_DIST_FOLDER_NAME -p 9999

Et dans le fichier backend, votre pourrait être quelque chose comme ça.

const express = require('express');
const webpush = require('web-Push');
const cors = require('cors');
const bodyParser = require('body-parser');

const PUBLIC_VAPID = 'PUBLIC_VAPID_KEY';
const PRIVATE_VAPID = 'PRIVATE_VAPID_KEY';

const fakeDatabase = [];

const app = express();

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

webpush.setVapidDetails('mailto:[email protected]', PUBLIC_VAPID, PRIVATE_VAPID);

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

app.post('/sendNotification', (req, res) => {
  const notificationPayload = {
    {"notification":
       { 
        "body":"This is a message.",
        "title":"Push MESSAGE",
        "vibrate":300,100,400,100,400,100,400],
        "icon":"ICON_URL",
        "tag":"Push demo",
        "requireInteraction":true,
        "renotify":true,
        "data":
          { "url":"https://google.com"}
       }
    }
  };

  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');
});

Dans l'URL, vous pouvez entrer votre URL et en cliquant sur Notification, votre notification Push ouvrira le lien indiqué et le focalisera dans le navigateur.

0
cyperpunk