How to Implement Web Push Notifications in Ruby on Rails (From Scratch!)
Ever felt like your users just need a gentle nudge—or maybe a not-so-gentle reminder—that you still exist? Well, web push notifications are your new best friend! They’re like little love notes from your app, popping up to say, “Hey, don’t forget about me!” And the best part? Your users don’t even need to be on your site. Today, we’re diving into how you can sprinkle this magic into your Rails app, step by step. And yes, we’ll be throwing in some code—real, working code—because we’re not just here to chat. Ready? Let’s rock and roll! 🛠️
Step 1: Setting Up Your Rails App
First things first—make sure you have a Rails app that’s ready to receive some serious love. If you’re starting from scratch (and who doesn’t love a fresh start?):
rails new push_notifier
cd push_notifier
Once your app is up and running, let’s add the secret sauce:
# Gemfile
gem 'web-push'
gem 'serviceworker-rails'
Now, give bundle install a whirl and let those gems sparkle!
Step 2: Generate Your VAPID Keys
VAPID keys are like your app’s official badge. Without them, your notifications are just rogue agents, wandering the web without a purpose.
# Run this in your terminal
vapid_key = WebPush.generate_key
puts "VAPID Public Key: #{vapid_key.public_key}"
puts "VAPID Private Key: #{vapid_key.private_key}"
Pro tip: Keep these keys somewhere safe—preferably not scribbled on a Post-it. They’re the keys to the kingdom!
Step 3: Setting Up the Database Tables
Alright, let’s talk data. You need to have a place to store all this web-push goodness. This isn’t just a fling; we’re building something that lasts!
3.1 Create the subscriptions Table
To store user subscriptions, let’s create a table. Think of it as our little black book for push notifications
rails generate migration CreateSubscriptions
Now, let’s lay down the structure in the generated migration file:
# db/migrate/[timestamp]_create_subscriptions.rb
class CreateSubscriptions < ActiveRecord::Migration[6.1]
def change
create_table :subscriptions do |t|
t.references :user, null: false, foreign_key: true
t.text :endpoint, null: false
t.text :p256dh_key, null: false
t.text :auth_key, null: false
t.timestamps
end
add_index :subscriptions, :endpoint, unique: true
end
end
Explanation (With a Side of Sass):
Now, let’s make it official:
rails db:migrate
Step 4: Setting Up the Service Worker
Your service worker is the unsung hero of this whole operation. It’s the one that actually handles the notifications when they come in. Think of it as your app’s butler, ready to deliver messages with a bow.
Recommended by LinkedIn
// app/assets/javascripts/serviceworker.js
self.addEventListener('push', function(event) {
const data = event.data.json();
self.registration.showNotification(data.title, {
body: data.message,
icon: '/path-to-your-icon.png'
});
});
And don’t forget to let Rails know who’s handling the butler duties:
# config/initializers/serviceworker.rb
Rails.application.config.serviceworker.routes.draw do
match "/serviceworker.js"
end
Step 5: Frontend Magic (Subscribing to Notifications)
Now let’s convince your users to subscribe. It’s like asking someone to follow you on social media, except way cooler. Here’s how you can do it:
// app/assets/javascripts/application.js
navigator.serviceWorker.register('/serviceworker.js')
.then(function(registration) {
console.log('Service Worker registered with scope:', registration.scope);
return registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription === null) {
// No subscription, time to charm the user
return registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: 'Your_VAPID_Public_Key'
});
}
return subscription;
});
})
.then(function(subscription) {
console.log('User is subscribed:', subscription);
// Time to seal the deal
})
.catch(function(error) {
console.error('Oops! Something went wrong:', error);
});
Once subscribed, your app needs to save this valuable relationship:
function sendSubscriptionToServer(subscription) {
fetch('/subscriptions', {
method: 'POST',
body: JSON.stringify({
subscription: subscription.toJSON()
}),
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
}
});
}
Step 6: Handling Subscriptions on the Backend
Your users have said “yes” to notifications. Time to make it official on the backend.
6.1 Creating the Subscription Model
In case you skipped the previous section (you rebel), here’s how to generate the model:
rails generate model Subscription user:references endpoint:text p256dh_key:text auth_key:text
6.2 Creating the Subscriptions Controller
Now, let’s create a controller to manage these relationships:
# app/controllers/subscriptions_controller.rb
class SubscriptionsController < ApplicationController
def create
subscription_params = params.require(:subscription).permit(:endpoint, :p256dh_key, :auth_key)
current_user.subscriptions.create(subscription_params)
render json: { message: "Subscription created successfully" }, status: :created
end
def destroy
subscription = current_user.subscriptions.find_by(endpoint: params[:endpoint])
subscription.destroy if subscription
render json: { message: "Subscription deleted successfully" }, status: :ok
end
end
Step 7: Sending Notifications from Your Rails App
Now that your users are all in, let’s send them something fun!
# app/controllers/notifications_controller.rb
class NotificationsController < ApplicationController
def create
subscription = current_user.subscriptions.find(params[:subscription_id])
message = {
title: 'Greetings from Rails!',
message: 'You just got a push notification. How cool is that?'
}
WebPush.payload_send(
endpoint: subscription.endpoint,
message: JSON.generate(message),
p256dh: subscription.p256dh_key,
auth: subscription.auth_key,
vapid: {
subject: 'mailto:your-email@example.com',
public_key: ENV['VAPID_PUBLIC_KEY'],
private_key: ENV['VAPID_PRIVATE_KEY']
}
)
render json: { message: "Notification sent successfully" }, status: :ok
end
end
Step 8: Testing It Out
Ready for the moment of truth? Fire up your Rails server, visit your site, and hit that subscribe button. Then trigger a notification and watch the magic unfold!
rails server
Final Thoughts
And there you have it! You’ve just implemented web push notifications in your Rails app from scratch, with a little bit of sass and a whole lot of code. Now, your users can receive your love notes even when they’re off doing other things. How awesome is that? 😎
If you enjoyed this guide or have any questions, drop a comment below. Let’s keep the conversation going—your thoughts might just inspire my next article!
#Rails #WebPush #Notifications #RubyOnRails #CodingIsFun