Skip to content

Rodrigo Urubatan – About Code

Helping ruby developers to use the best tools for each job so they can solve hard problems, with less bugs and have more free time.

Menu
  • Home
  • My last presentations
  • About
  • Privacy Policy
Menu

How to integrate Ruby on Rails and Google Firebase to send offline notifications to your users!

Posted on 2018-01-07 by Rodrigo Urubatan

First, firebase is not the only solution for this, but I like their approach, it is simple and multi platform, and really easy to integrate in a rails application.

Of course Firebase has a lot more features, but to keep this post short, we’ll focus only on this feature today.

Remember that to use it in production your application needs to be acessed through SSL, the ServiceWorker API only works through SSL.

And before we start coding, you’ll need to go to the Firebase Console and create a new application for you there.

But lets start with the Rails application, create a new rails app with the ” rails new app_name”  command.

Now create a file named manifest.json in the public directory, this file is simple and will be your Portable Web Application manifest.

{
  "name": "My  First PWA On Rails",
  "short_name": "PWAOnRails",
  "start_url": "/",
  "icons": [
    {
      "src": "/my_icon.png",
      "sizes": "256",
      "type": "image/png"
    }
  ],
  "theme_color": "#000000",
  "background_color": "#FFFFFF",
  "display": "standalone",
  "orientation": "portrait",
  "gcm_sender_id": "103953800507"

}

The sender ID 103953800507 is a fixed number Firebase uses, do not put your project firebase id there.

Then we need to create also in the public directory a file named “firebase-messaging-sw.js” to host the Firebase javascript initialization code, the content of this file is provided by the firebase web framework.

importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
importScripts('/firebase/init.js');

firebase.messaging();

The only missing piece is the firebase/init.js file that will hold your firebase application configuration, the values for this file will come from the application you’ve created previously in the console.

// Initialize Firebase
var config = {
    apiKey: "YOUR_API_KEY",
    authDomain: "YOUR_APP.firebaseapp.com",
    databaseURL: "https://YOUR_APP.firebaseio.com",
    projectId: "YOUR_PROJECT_ID",
    storageBucket: "",
    messagingSenderId: "THIS_IS_YOUR_REAL_SENDER_ID"
};
firebase.initializeApp(config);

We are almost done with the application initialization, now we need to tell the browsers that we want the service worker loaded, to do that, lets use the firebase javascript code, we’ll just add a similar piece of code to the main application layout.

    <script src="https://www.gstatic.com/firebasejs/4.8.1/firebase.js"></script>
    <script>
        // Initialize Firebase
        var config = {
            apiKey: "YOUR_API_KEY",
            authDomain: "YOUR_APP.firebaseapp.com",
            databaseURL: "https://YOUR_APP.firebaseio.com",
            projectId: "YOUR_PROJECT_ID",
            storageBucket: "",
            messagingSenderId: "THIS_IS_YOUR_REAL_SENDER_ID"
        };
        firebase.initializeApp(config);
    </script>

With that done, we need to start integrating the Firebase API with our rails application (yes, I know, we didn’t do anything in rails yet…), and to start we’ll create another javascript file, now in our application assets file, I’ll call it “first_pwa.js”.

function FirstApp() {
    this.saveMessagingDeviceToken = function () {
        firebase.messaging().getToken().then(function (currentToken) {
            if (currentToken) {
                console.log('Got FCM device token:', currentToken);
                $.post("/push_registrations", {subscription: currentToken});
            } else {
                // Need to request permissions to show notifications.
                this.requestNotificationsPermissions();
            }
        }.bind(this)).catch(function (error) {
            console.error('Unable to get messaging token.', error);
        });
    }
    this.requestNotificationsPermissions = function() {
        console.log('Requesting notifications permission...');
        firebase.messaging().requestPermission().then(function() {
            // Notification permission granted.
            this.saveMessagingDeviceToken();
        }.bind(this)).catch(function(error) {
            console.error('Unable to get permission to notify.', error);
        });
    };
}
var firstApp = new FirstApp();
firstApp.saveMessagingDeviceToken();

This code will ask the user for permissions to show notifications, these notifications work online or offline, and more importantly will send the firebase messaging token to the “push_registrations”  controller, now we just need to create this controller, use the approach you prefer, I just create the file using a text editor, the content for now is really simple, just to show how to use it…

class PushRegistrationsController < ApplicationController
  def create
    puts  params[:subscription]
    User.find_or_create_by push_sub: params[:subscription]
  end
end

We are saving the user subscription ID in a User model, for this sample, I just created the model with the command:

rails g model user push_sub:string

And we can create another controller to broadcast messages to everyone that has already opened the application, but to do that we’ll need a REST client, the easier to use for this sample is the ‘rest-client’ gem, please add the following entry to the Gemfile and run “bundle install”

gem 'rest-client'

You’ll need to get a server application key for your Firebase Messaging app from their web site.

And the broadcast controller will look similar to this:

class BroadcastsController < ApplicationController
	def index
		headers = {"Content-Type": "application/json",
			"Authorization": "key=YOUR_SERVER_KEY"}
		url = "https://fcm.googleapis.com/fcm/send"
		User.find_each do |user|
			payload = {
				"notification": {
					"title": "We have a message for you!",
					"body": "Answer please, we are cool!",
					"icon": "/app_icon.png",
					"click_action": "https://oursecureurl.domain.com/chats"
					},
				"to": user.push_sub
			}
			RestClient.post(url, payload, headers)
     	end
	end
end

If the application is not running in the moment you send the message, a notification will be displayed for the user automatically, but if the application is running, meaning, if the user is in your web site, you need to handle the message in your code, the code is still simple, just a little more javascript.

Lets open the “firebase-messaging-sw.js” and change the last line and add a few more:

importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');
importScripts('/firebase/init.js');

const messaging = firebase.messaging();

messaging.onMessage(function(payload) {
  console.log("Message received. ", payload);
  // ...
});

Of course you can use the firebase API to create topics and device groups to make it easy to send message to many devices of one user, or to notify everyone that a specific product is on sale.

But this is the basics for the first PWA on Rails with offline notifications.

 

 

 

Related

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent posts

  • Why Embrace Nesting in Ruby Modules?
  • An easy way to have a local “Github Copilot” for free
  • SPA without touching Javascript – The magic of Ruby on rails and Hotwire
  • I see Dead Jobs everywhere (sidekiq DeadSet)
  • Quick tips that help: rails notes

Arquives

  • May 2024
  • April 2024
  • February 2023
  • January 2023
  • December 2022
  • June 2021
  • March 2020
  • January 2020
  • July 2019
  • June 2019
  • May 2019
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • February 2018
  • January 2018
  • November 2017
  • August 2015
  • August 2014
  • July 2014
  • August 2007

Categories

  • AI
  • articles
  • cfp
  • firebase
  • gems
  • git
  • opinion
  • presentations
  • projects
  • rails6
  • ruby
  • Sem categoria
  • server-api
  • tutorials
  • Uncategorized
© 2025 Rodrigo Urubatan – About Code | Powered by Minimalist Blog WordPress Theme