From a13a474c239c77d523cf95ec5b6404396bdcf940 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Fri, 5 Jun 2020 00:15:50 +0530 Subject: [PATCH] Chore: Firebase Cloud Messaging Support (#858) --- .env.example | 3 ++ Gemfile | 1 + Gemfile.lock | 3 ++ .../notification_subscription_builder.rb | 2 ++ app/models/notification_subscription.rb | 2 +- .../notification/push_notification_service.rb | 18 ++++++++++- .../push_notification_service_spec.rb | 32 +++++++++++++++++++ 7 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 spec/services/notification/push_notification_service_spec.rb diff --git a/.env.example b/.env.example index d4fb1ea12..e8ec635f0 100644 --- a/.env.example +++ b/.env.example @@ -102,6 +102,9 @@ CHARGEBEE_WEBHOOK_PASSWORD= ## generate a new key value here : https://d3v.one/vapid-key-generator/ # VAPID_PUBLIC_KEY= # VAPID_PRIVATE_KEY= +# +# for mobile apps +# FCM_SERVER_KEY= ## Bot Customizations USE_INBOX_AVATAR_FOR_BOT=true diff --git a/Gemfile b/Gemfile index 50e3e2ce8..6d16179ea 100644 --- a/Gemfile +++ b/Gemfile @@ -84,6 +84,7 @@ gem 'sidekiq' gem 'flag_shih_tzu' ##-- Push notification service --## +gem 'fcm' gem 'webpush' group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 48e4e12a8..d8979b903 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -189,6 +189,8 @@ GEM multipart-post (>= 1.2, < 3) faraday_middleware (1.0.0) faraday (~> 1.0) + fcm (1.0.1) + faraday (~> 1.0.0) ffi (1.12.2) flag_shih_tzu (0.3.23) foreman (0.87.1) @@ -547,6 +549,7 @@ DEPENDENCIES facebook-messenger factory_bot_rails faker + fcm flag_shih_tzu foreman google-cloud-storage diff --git a/app/builders/notification_subscription_builder.rb b/app/builders/notification_subscription_builder.rb index 05b0bf984..3326b5cde 100644 --- a/app/builders/notification_subscription_builder.rb +++ b/app/builders/notification_subscription_builder.rb @@ -12,6 +12,8 @@ class NotificationSubscriptionBuilder def identifier @identifier ||= params[:subscription_attributes][:endpoint] if params[:subscription_type] == 'browser_push' + @identifier ||= params[:device_id] if params[:subscription_type] == 'fcm' + @identifier end def identifier_subscription diff --git a/app/models/notification_subscription.rb b/app/models/notification_subscription.rb index 534bced01..dbe148f71 100644 --- a/app/models/notification_subscription.rb +++ b/app/models/notification_subscription.rb @@ -22,7 +22,7 @@ class NotificationSubscription < ApplicationRecord SUBSCRIPTION_TYPES = { browser_push: 1, - gcm: 2 + fcm: 2 }.freeze enum subscription_type: SUBSCRIPTION_TYPES diff --git a/app/services/notification/push_notification_service.rb b/app/services/notification/push_notification_service.rb index e01d19679..c29796d64 100644 --- a/app/services/notification/push_notification_service.rb +++ b/app/services/notification/push_notification_service.rb @@ -7,7 +7,8 @@ class Notification::PushNotificationService return unless user_subscribed_to_notification? notification_subscriptions.each do |subscription| - send_browser_push(subscription) if subscription.browser_push? + send_browser_push(subscription) + send_fcm_push(subscription) end end @@ -53,6 +54,8 @@ class Notification::PushNotificationService end def send_browser_push(subscription) + return unless subscription.browser_push? + Webpush.payload_send( message: JSON.generate(push_message), endpoint: subscription.subscription_attributes['endpoint'], @@ -70,4 +73,17 @@ class Notification::PushNotificationService rescue Webpush::ExpiredSubscription subscription.destroy! end + + def send_fcm_push(subscription) + return unless subscription.fcm? + + fcm = FCM.new(ENV['FCM_SERVER_KEY']) + options = { "notification": { + "title": notification.notification_type.titleize, + "body": push_message_title, + "notification": notification.to_json + } } + response = fcm.send([subscription.subscription_attributes['push_token']], options) + subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error') + end end diff --git a/spec/services/notification/push_notification_service_spec.rb b/spec/services/notification/push_notification_service_spec.rb new file mode 100644 index 000000000..67fc9f999 --- /dev/null +++ b/spec/services/notification/push_notification_service_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +describe Notification::PushNotificationService do + let!(:account) { create(:account) } + let!(:user) { create(:user, account: account) } + let!(:notification) { create(:notification, user: user, account: user.accounts.first) } + let(:fcm_double) { double } + + before do + allow(Webpush).to receive(:payload_send).and_return(true) + allow(FCM).to receive(:new).and_return(fcm_double) + allow(fcm_double).to receive(:send).and_return({ body: { 'results': [] }.to_json }) + end + + describe '#perform' do + it 'sends webpush notifications for webpush subscription' do + create(:notification_subscription, user: notification.user) + + described_class.new(notification: notification).perform + expect(Webpush).to have_received(:payload_send) + expect(FCM).not_to have_received(:new) + end + + it 'sends a fcm notification for firebase subscription' do + create(:notification_subscription, user: notification.user, subscription_type: 'fcm') + + described_class.new(notification: notification).perform + expect(FCM).to have_received(:new) + expect(Webpush).not_to have_received(:payload_send) + end + end +end