【问题标题】:Angular 7 PWA configure Push NotificationsAngular 7 PWA 配置推送通知
【发布时间】:2019-04-21 03:56:27
【问题描述】:

我正在使用 Angular 7 创建 PWA,但我正在努力处理推送通知。

我使用 SWPush 和 Vapid 密钥对以 thisthis 的身份关注教程。我能够订阅和取消订阅,而且我的服务器部分也能正常工作,但不幸的是,教程并未涵盖在应用程序中显示实际通知。

据我了解,通知应该会自动弹出,而无需在代码中调用它,对吧?您只需订阅,其余的由 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)
      });
   });
}

但这似乎只在应用程序/页面处于前台时才有效。否则我会收到类似“网站已在后台更新”的通知。显然我在这里做错了什么。但是什么?

  1. 当应用程序在后台时,我必须做什么才能显示通知?

  2. 有没有办法处理通知上的点击事件?

这里的 ng 文档真的很少。

【问题讨论】:

  • 您还有一份文档要查看,您是否尝试过this documentation 的网络基础知识?
  • 谢谢,是的,我已经看到了,最后这就是我上面的代码正在做的事情。但是,当应用程序处于后台时,它似乎不起作用:-/

标签: angular push-notification service-worker progressive-web-apps web-push


【解决方案1】:

经过一番努力,我找到了一些东西并将其分享给其他人:

挖掘通过运行 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$5(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;
}

因此,没有显示通知,但浏览器在后台报告了更新。 希望这对某人有所帮助。

【讨论】:

  • @Silviu:我修改了服务器端,以 ngsw 想要的形式发送有效负载。如果你使用相同的设置(laravel/webpush),我可以告诉你我到底做了什么。
  • 我明白了。我们使用 OneSignal,我不知道如何将您的解决方案应用于我的案例。谢谢
  • @Silviu 如果您无法定义有效负载 bc。对于 onesignal,您可以尝试另外实现自定义 sw 并覆盖推送通知的内容。看看这个关于如何创建一个额外的 serviceworker。 stackoverflow.com/questions/55256689/… 然后尝试从 angular 创建的脚本中复制推送通知处理(一旦您运行 angular build)并根据您的有效负载对其进行修改。安装第二个 serviceworker 脚本效果很好,其余的我没有测试。
【解决方案2】:

有没有办法处理通知上的点击事件?

试试这个:

this.swPush.notificationClicks.subscribe(data => {
    // handle click
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-17
    • 2021-06-11
    • 2019-04-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 1970-01-01
    相关资源
    最近更新 更多