Angular 7 pwa / SwPush - push-уведомления не работают

Я пытаюсь заставить push-уведомления работать в Angular 7, используя ссылку и с помощью SwPush. Я не могу получать push-уведомления. В настоящее время я работаю на localhost (запустив http-сервер после выполнения ng-build), а мой сервер api находится в облаке. Мне удалось включить подписку с помощью swPush.requestSubscription, и подписка успешно зарегистрирована на сервере. В Chrome все вызовы api блокируются самим сервисным воркером (сбой: сервисным воркером), в то время как в Firefox ошибки нет, но push-сообщение не появляется.

Ниже я добавил соответствующие фрагменты кода. Поскольку сообщений о конкретных ошибках не поступало, я не могу продолжить.

Посоветуйте, пожалуйста, как заставить это работать и показывать уведомления.

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

person ramya krishna    schedule 17.12.2018    source источник
comment
у вас https ?. PWA не будет работать со сборкой разработчика.   -  person Dharan G    schedule 25.12.2018
comment
можете ли вы воспроизвести ошибку с помощью stackblitz (stackblitz.com)?   -  person Dharan G    schedule 25.12.2018
comment
@DharanG Я тестирую его в локальной среде, а не в dev.   -  person ramya krishna    schedule 04.01.2019


Ответы (3)


Вам необходимо установить Angular CLI, PWA для сервис-воркера, webpush для генерации ключей VAPID и http-сервер для запуска фиктивного сервера. Вы можете сделать это, запустив:

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

Теперь вам нужно сгенерировать пару ключей VAPID с помощью webpush, чтобы использовать ее во внешнем и внутреннем интерфейсе.

web-push generate-vapid-keys --json

Сохраните где-нибудь сгенерированную пару. Используйте приведенный ниже код в app.component.ts, чтобы запросить подписку у пользователя.

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 - это открытый ключ, который вы получили ранее.

Добавьте это в свой проект Angular внутри 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));
            }
        });

Вы можете ввести приведенный выше код там, где вы найдете следующую строку внутри файла> это будет строка номер 1893.

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

И вам нужно заново построить дист, чтобы это сработало. Теперь используйте

ng build --prod

чтобы сгенерировать dist и обслужить его, используя

http-server ./dist/YOUR_DIST_FOLDER_NAME -p 9999

И в бэкэнд-файле у вас должно быть что-то вроде этого.

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

Внутри URL-адреса вы можете ввести свой URL-адрес, и при нажатии на уведомление ваше push-уведомление откроет данную ссылку и сфокусирует ее в браузере.

person cyperpunk    schedule 25.02.2019
comment
Я сделал то же самое, но не получаю уведомления в Chrome (версия 72.0.3626.119). В firefox он работает - person Shifs; 29.03.2019
comment
Можете ли вы попробовать еще раз, обновив Chrome? Запустите рабочий режим и попробуйте еще раз. - person cyperpunk; 15.04.2019
comment
Наконец, вы можете снова попробовать обновить свои пакеты ng add @ angular / pwa, npm i webpush и npm i http-server -g. И перезапустите свой проект. - person cyperpunk; 15.04.2019

чтобы сервис-воркер работал, вам нужно скомпилировать с --prod. попробуйте скомпилировать с помощью ng build --prod

person daniel    schedule 14.01.2019
comment
Service worker не будет активирован только при запуске в режиме prod. Веб-сайт должен работать в https, чтобы обслуживающий работник мог работать. - person cyperpunk; 10.05.2020

В моем случае уведомления Google Chrome были отключены на моем компьютере с Windows в настройках Уведомления и действия.

person Mardari    schedule 09.10.2019