简体   繁体   中英

Identifying users in Rails Web push notifications

I'm developing a Rails application, and I'd like to send web push notifications to specific users when certain actions happen, eg:

A user started tracking a timer, but the timer has been running for more than 6 hours. Then the app sends that user a web notification.

I've been doing research and found this tutorial , the author implements push notifications for Rails, however there's no insight on how to identify the users.

From what I understood, the users needs to subscribe from their browser to be able to get push notifications, however, considering each user can use the application from multiple browsers, how can I automatically subscribe/unsubscribe a user for notifications in all browsers they use the app from?

So, what I did was adding a notification_subscription model to my User model.

On my javascript, I check if there's a current browser subscription present:

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

     this.subscribe();
  });
});

I check if the current subscription is already present in the user stored endpoints, and subscribe if it isn't.

On subscription I send the new endpoint to the backend, which adds the new subscription to the user:

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

Then I can send notifications to users to every endpoint:

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

The webpush gem raises an InvalidSubscription exception if the endpoint is invalid, we can destroy that endpoint to keep only the valid endpoints from the user.

该端点在浏览器中是唯一的,因此您需要在应用程序顶部使用其他身份验证方案,以将用户信息与新端点一起发送。

You need to attach metadata (ie the user ID) to the endpoint when you store it on your server:

@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]

In the second case I suggest to sign the user ID or use a secret token, otherwise anyone would be able to subscribe to push notifications as if it was another user.

Then you can delete from the database all the endpoints that belong to that user ID to unsubscribe all his devices.

However I don't think it's a good practice: a user may want to receive notifications on a device and not on another one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM