Setting Up Push Notifications in Rails
1. Installing Web Push Gem
Rails does not have built-in support for push notifications, so we use the web-push
gem:
bundle add web-push
Next, generate VAPID (Voluntary Application Server Identification) keys, which authenticate push requests:
webpush generate_key
This outputs a public and private key. Add them to config/secrets.yml
:
development:
vapid_public_key: "YOUR_PUBLIC_KEY"
vapid_private_key: "YOUR_PRIVATE_KEY"
2. Setting Up Subscription Endpoints
In the Rails backend, create an API endpoint to store push subscriptions. This will handle incoming subscription data from the frontend, which typically includes the endpoint URL and encryption keys.
class PushSubscriptionsController < ApplicationController
def create
subscription = PushSubscription.find_or_initialize_by(endpoint: params[:endpoint])
subscription.update!(keys: params[:keys].to_json)
render json: { message: "Subscribed successfully" }
end
end
And define the route in config/routes.rb
:
post "/push_subscriptions", to: "push_subscriptions#create"
Now, when a user subscribes, their subscription details will be stored in the database for future use.
3. Creating the PushSubscription Model
In section 2, we are using the PushSubscription
model to store the subscription data. However, the web-push
gem does not automatically create this model for you. You’ll need to create the model manually.
Follow these steps to set up the PushSubscription
model:
3.1. Generate the Model
First, generate the PushSubscription
model using the Rails generator. This model will store the endpoint
(the URL to which notifications are sent) and the keys
(encryption keys for the subscription).
rails generate model PushSubscription endpoint:string keys:text
This will create the necessary migration file and a model file at app/models/push_subscription.rb
.
3.2. Run the Migration
After generating the model, run the migration to create the push_subscriptions
table in the database:
rails db:migrate
3.3. The PushSubscription Model
Next, open the generated model file app/models/push_subscription.rb
. You can define validations or any additional logic, but here’s a simple version of the model:
class PushSubscription < ApplicationRecord
# Add any necessary validations here, for example:
validates :endpoint, presence: true
validates :keys, presence: true
end
This model will now be used to store the subscription data coming from the frontend.
3.4. Updating the Controller
The PushSubscriptionsController
we wrote earlier will now be able to interact with the PushSubscription
model to save subscription data.
Here’s the PushSubscriptionsController
code again for reference:
class PushSubscriptionsController < ApplicationController
def create
subscription = PushSubscription.find_or_initialize_by(endpoint: params[:endpoint])
subscription.update!(keys: params[:keys].to_json)
render json: { message: "Subscribed successfully" }
end
end
4. Sending Notifications from Rails
Once the subscriptions are stored in the database, we can send push notifications.
The web-push
gem allows us to send push notifications to all stored subscriptions.
We can set this up in a background job or through a simple controller action.
To send a notification, modify PushNotificationsController
:
require "webpush"
class PushNotificationsController < ApplicationController
def send_notification
subscription = PushSubscription.last
payload = { title: "New Update!", body: "Check out the latest features!" }
Webpush.payload_send(
message: payload.to_json,
endpoint: subscription.endpoint,
p256dh: JSON.parse(subscription.keys)["p256dh"],
auth: JSON.parse(subscription.keys)["auth"],
vapid: {
public_key: Rails.application.credentials.dig(:vapid_public_key),
private_key: Rails.application.credentials.dig(:vapid_private_key)
}
)
render json: { message: "Notification sent!" }
end
end
Now, we can trigger notifications using:
curl -X POST http://localhost:3000/send_notification
This way, we can send notifications to all the users who have subscribed.
By following these steps, we'll have a complete push notification system set up with Rails using the web-push
gem.
The PushSubscription
model stores the necessary data, and the controller
is ready to handle the subscription process and send notifications when needed.