Angular 7 PWA 配置推送通知
Angular 7 PWA configure Push Notifications
我正在使用 angular 7 创建一个 PWA,但我正在努力处理推送通知。
我按照 this and this 的教程使用 SWPush 和 Vapid 密钥对。我能够订阅和取消订阅,我的服务器部分也能正常工作,但不幸的是,教程不包括在应用程序中显示实际通知。
按照我的理解,通知应该是自动弹出的,不需要在代码中调用它,对吧?。您只需订阅,ngsw 会完成剩下的工作。不幸的是,他们没有出现在我的案例中。我只能通过在代码中手动调用它们来显示它们:
this.swPush.messages.subscribe(
(notification: any) => {
console.log("received push message", notification);
let options = {
body: notification.body,
icon: "assets/icon/favicon.png",
actions: <any>notification.actions,
data: notification.data,
vibrate: [100, 50, 10, 20, 20]
};
this.showNotification(notification.title, options)
},
err => {
console.error(err);
}
);
[...]
showNotification(title: string, options: NotificationOptions) {
navigator.serviceWorker.getRegistration().then(reg => {
reg.showNotification(title, options).then(res => {
console.log("showed notification", res)
}, err => {
console.error(err)
});
});
}
但这似乎只有在 app/page 处于前台时才有效。否则我会收到类似 "The site has been updated in the background" 的通知。显然我做错了什么here.But什么?
当应用程序处于后台时,我需要做什么才能显示通知?
有没有办法处理通知的点击事件?
这里的 ng 文档真的很少。
Is there a way to handle click events on the notifications?
试试这个:
this.swPush.notificationClicks.subscribe(data => {
// handle click
})
经过大量的努力,我找到了一些东西并将其分享给其他人:
深入研究由 运行 build --prod 创建的 ngsw-worker.js 有这个函数:
onPush(msg) {
// Push notifications without data have no effect.
if (!msg.data) {
return;
}
// Handle the push and keep the SW alive until it's handled.
msg.waitUntil(this.handlePush(msg.data.json()));
}
...
handlePush(data) {
return __awaiter(this, void 0, void 0, function* () {
yield this.broadcast({
type: 'PUSH',
data,
});
if (!data.notification || !data.notification.title) {
return;
}
const desc = data.notification;
let options = {};
NOTIFICATION_OPTION_NAMES.filter(name => desc.hasOwnProperty(name))
.forEach(name => options[name] = desc[name]);
yield this.scope.registration.showNotification(desc['title'], options);
});
}
看起来angular 为您订阅并显示通知,因此没有必要在您自己的代码中订阅并显示它。
我的发送库 (https://github.com/laravel-notification-channels/webpush) 有问题,它发送的有效负载是这样的:
payload = {"title":"test","actions":[{"title":"View App","action":"view_app"}],"body":"test","icon":"\/icon.png","data":{"id":"21a3804e-6d71-4a56-b513-535709c37c0f"}}
但是 angular 显然期望是这样的:
payload = {
"notification":{"title":"test","actions":[{"title":"View App","action":"view_app"}],"body":"test","icon":"\/icon.png","data":{"id":"21a3804e-6d71-4a56-b513-535709c37c0f"}}
}
导致 ngsw-worker.js 中的这一行失败:
if (!data.notification || !data.notification.title) {
return;
}
因此,没有显示任何通知,但浏览器在后台报告有更新。
希望这对某人有所帮助。
我正在使用 angular 7 创建一个 PWA,但我正在努力处理推送通知。
我按照 this and this 的教程使用 SWPush 和 Vapid 密钥对。我能够订阅和取消订阅,我的服务器部分也能正常工作,但不幸的是,教程不包括在应用程序中显示实际通知。
按照我的理解,通知应该是自动弹出的,不需要在代码中调用它,对吧?。您只需订阅,ngsw 会完成剩下的工作。不幸的是,他们没有出现在我的案例中。我只能通过在代码中手动调用它们来显示它们:
this.swPush.messages.subscribe(
(notification: any) => {
console.log("received push message", notification);
let options = {
body: notification.body,
icon: "assets/icon/favicon.png",
actions: <any>notification.actions,
data: notification.data,
vibrate: [100, 50, 10, 20, 20]
};
this.showNotification(notification.title, options)
},
err => {
console.error(err);
}
);
[...]
showNotification(title: string, options: NotificationOptions) {
navigator.serviceWorker.getRegistration().then(reg => {
reg.showNotification(title, options).then(res => {
console.log("showed notification", res)
}, err => {
console.error(err)
});
});
}
但这似乎只有在 app/page 处于前台时才有效。否则我会收到类似 "The site has been updated in the background" 的通知。显然我做错了什么here.But什么?
当应用程序处于后台时,我需要做什么才能显示通知?
有没有办法处理通知的点击事件?
这里的 ng 文档真的很少。
Is there a way to handle click events on the notifications?
试试这个:
this.swPush.notificationClicks.subscribe(data => {
// handle click
})
经过大量的努力,我找到了一些东西并将其分享给其他人:
深入研究由 运行 build --prod 创建的 ngsw-worker.js 有这个函数:
onPush(msg) {
// Push notifications without data have no effect.
if (!msg.data) {
return;
}
// Handle the push and keep the SW alive until it's handled.
msg.waitUntil(this.handlePush(msg.data.json()));
}
...
handlePush(data) {
return __awaiter(this, void 0, void 0, function* () {
yield this.broadcast({
type: 'PUSH',
data,
});
if (!data.notification || !data.notification.title) {
return;
}
const desc = data.notification;
let options = {};
NOTIFICATION_OPTION_NAMES.filter(name => desc.hasOwnProperty(name))
.forEach(name => options[name] = desc[name]);
yield this.scope.registration.showNotification(desc['title'], options);
});
}
看起来angular 为您订阅并显示通知,因此没有必要在您自己的代码中订阅并显示它。 我的发送库 (https://github.com/laravel-notification-channels/webpush) 有问题,它发送的有效负载是这样的:
payload = {"title":"test","actions":[{"title":"View App","action":"view_app"}],"body":"test","icon":"\/icon.png","data":{"id":"21a3804e-6d71-4a56-b513-535709c37c0f"}}
但是 angular 显然期望是这样的:
payload = {
"notification":{"title":"test","actions":[{"title":"View App","action":"view_app"}],"body":"test","icon":"\/icon.png","data":{"id":"21a3804e-6d71-4a56-b513-535709c37c0f"}}
}
导致 ngsw-worker.js 中的这一行失败:
if (!data.notification || !data.notification.title) {
return;
}
因此,没有显示任何通知,但浏览器在后台报告有更新。 希望这对某人有所帮助。