【问题标题】:Identifying users in Rails Web push notifications在 Rails Web 推送通知中识别用户
【发布时间】:2017-03-23 13:04:11
【问题描述】:

我正在开发一个 Rails 应用程序,我想在某些操作发生时向特定用户发送网络推送通知,例如:

用户开始跟踪计时器,但计时器已运行超过 6 小时。然后,应用会向该用户发送网络通知。

我一直在做研究,发现this tutorial,作者为Rails实现了推送通知,但是没有关于如何识别用户的见解。

据我了解,用户需要从他们的浏览器订阅才能获得推送通知,但是,考虑到每个用户都可以从多个浏览器使用该应用程序,我怎样才能自动订阅/取消订阅用户的所有通知他们使用应用程序的浏览器?

【问题讨论】:

    标签: ruby-on-rails web-push


    【解决方案1】:

    所以,我所做的是将notification_subscription 模型添加到我的User 模型中。

    在我的 javascript 上,我检查是否存在当前的浏览器订阅:

    this.serviceWorkerReady()
      .then((serviceWorkerRegistration) => {
         serviceWorkerRegistration.pushManager.getSubscription()
         .then((pushSubscription) => {
            if (pushSubscription && _.includes(subscriptionEndpoints, pushSubscription.endpoint)) {
              return;
         }
    
         this.subscribe();
      });
    });
    

    我检查当前订阅是否已经存在于用户存储的端点中,如果不存在则订阅。

    在订阅时,我将新端点发送到后端,这会将新订阅添加到用户:

    $.post(Routes.users_subscriptions_path({ format: 'json' }), {
      subscription: subscription.toJSON()
    });
    

    然后我可以向每个端点的用户发送通知:

    def push_notifications_to_user(user)
        message = {
          title: "A message!",
          tag: 'notification-tag'
        }
    
        user.notification_subscriptions.each do |subscription|
          begin
            Webpush.payload_send(
              message: JSON.generate(message),
              endpoint: endpoint,
              p256dh: p256dh,
              auth: auth,
              api_key: public_key
            )
          rescue Webpush::InvalidSubscription => exception
            subscription.destroy
          end
        end
      end
    

    如果端点无效,webpush gem 会引发 InvalidSubscription 异常,我们可以销毁该端点以仅保留用户的有效端点。

    【讨论】:

      【解决方案2】:

      端点在浏览器中是唯一的,因此您需要在应用顶部添加一个额外的身份验证方案,以便将用户信息与新端点一起发送。

      【讨论】:

      • 你能扩展一下吗?我在我的应用程序中使用 Devise 进行身份验证,我当时在想的是存储用户的所有订阅并向所有这些订阅发送通知。但这对我来说听起来不太好,因为订阅可能过期,但没有太多关于它们如何实际过期的文档。
      • 正是如此,您需要将所有订阅打包保持在相同的应用程序级标识下。我会单独询问到期时间。
      【解决方案3】:

      当您将元数据(即用户 ID)存储在服务器上时,您需要将元数据(即用户 ID)附加到端点:

      @subscription = Subscriptions.new endpoint: params[:endpoint]
      
      @subscription.user = current_user
      // or if you send with AJAX the user id together with the endpoint 
      @subscription.user = User.find params[:user_id]
      

      在第二种情况下,我建议签署用户 ID 或使用秘密令牌,否则任何人都可以像其他用户一样订阅推送通知。

      然后您可以从数据库中删除属于该用户 ID 的所有端点以取消订阅他的所有设备。

      但我认为这不是一个好习惯:用户可能希望在一台设备上接收通知,而不是在另一台设备上。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-03
        • 1970-01-01
        • 2021-06-11
        • 1970-01-01
        相关资源
        最近更新 更多