Angular 7 @ angular/pwa link を使用し、SwPushを使用してプッシュ通知を機能させようとしています。実際のプッシュ通知を取得できません。現在ng-buildを実行した後でhttp-serverを実行することによりlocalhostで作業しており、apiサーバーがクラウドに配置されています。swPush.requestSubscriptionを使用してサブスクリプションを有効にでき、サブスクリプションはサーバーに正常に登録されています。Chromeでは、 Firefoxではエラーは発生しませんが、プッシュメッセージは表示されませんが、すべてのAPI呼び出しがサービスワーカー自体からブロックされます(失敗:サービスワーカーから)。
以下に関連するコードスニペットを追加しました。特定のエラーが報告されていないため、先に進むことができません。
これを機能させる方法と通知を表示する方法についてアドバイスしてください。
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')
}
}
}));
}
}
サービスワーカーが機能するには、-prodでコンパイルする必要があります。 ng build --prodを使用してコンパイルしてみます
Angular CLI、Service Worker用のPWA、VAPIDキーを生成するためのwebpush、およびモックサーバーを実行するためのhttp-serverをインストールする必要があります。次のコマンドを実行して実行できます。
npm i -g @angular/cli --save
ng add @angular/pwa --save
npm i webpush --save
npm i http-server -g --save
次に、フロントエンドとバックエンドで使用するためにwebpushを使用してVAPIDキーペアを生成する必要があります
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) => ..
そして、これを機能させるには、distを再度ビルドする必要があります。今使う
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を入力できます。通知をクリックすると、プッシュ通知が所定のリンクを開き、ブラウザにフォーカスします。
私の場合、Google Chrome notifications was my disabled on my Windows machine、in通知とアクションの設定。