class FCM
Constants
- BASE_URI
- BASE_URI_V1
- DEFAULT_TIMEOUT
- FORMAT
- GROUP_NOTIFICATION_BASE_URI
constants
- INSTANCE_ID_API
- TOPIC_REGEX
Attributes
api_key[RW]
json_key_path[RW]
project_base_uri[RW]
timeout[RW]
Public Class Methods
new(api_key, json_key_path = "", project_name = "", client_options = {})
click to toggle source
# File lib/fcm.rb, line 19 def initialize(api_key, json_key_path = "", project_name = "", client_options = {}) @api_key = api_key @client_options = client_options @json_key_path = json_key_path @project_base_uri = BASE_URI_V1 + project_name.to_s end
Public Instance Methods
add_registration_ids(key_name, project_id, notification_key, registration_ids)
click to toggle source
# File lib/fcm.rb, line 108 def add_registration_ids(key_name, project_id, notification_key, registration_ids) post_body = build_post_body(registration_ids, operation: "add", notification_key_name: key_name, notification_key: notification_key) extra_headers = { "project_id" => project_id, } for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection| response = connection.post("/gcm/notification", post_body.to_json) build_response(response) end end
Also aliased as: add
batch_subscribe_instance_ids_to_topic(instance_ids, topic_name)
click to toggle source
# File lib/fcm.rb, line 207 def batch_subscribe_instance_ids_to_topic(instance_ids, topic_name) manage_topics_relationship(topic_name, instance_ids, "Add") end
batch_topic_subscription(topic, registration_ids)
click to toggle source
# File lib/fcm.rb, line 167 def batch_topic_subscription(topic, registration_ids) manage_topics_relationship(topic, registration_ids, "Add") end
batch_topic_unsubscription(topic, registration_ids)
click to toggle source
# File lib/fcm.rb, line 171 def batch_topic_unsubscription(topic, registration_ids) manage_topics_relationship(topic, registration_ids, "Remove") end
batch_unsubscribe_instance_ids_from_topic(instance_ids, topic_name)
click to toggle source
# File lib/fcm.rb, line 211 def batch_unsubscribe_instance_ids_from_topic(instance_ids, topic_name) manage_topics_relationship(topic_name, instance_ids, "Remove") end
create_notification_key(key_name, project_id, registration_ids = [])
click to toggle source
# File lib/fcm.rb, line 92 def create_notification_key(key_name, project_id, registration_ids = []) post_body = build_post_body(registration_ids, operation: "create", notification_key_name: key_name) extra_headers = { "project_id" => project_id, } for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection| response = connection.post("/gcm/notification", post_body.to_json) build_response(response) end end
Also aliased as: create
get_instance_id_info(iid_token, options = {})
click to toggle source
# File lib/fcm.rb, line 190 def get_instance_id_info(iid_token, options = {}) params = options for_uri(INSTANCE_ID_API) do |connection| response = connection.get("/iid/info/" + iid_token, params) build_response(response) end end
manage_topics_relationship(topic, registration_ids, action)
click to toggle source
# File lib/fcm.rb, line 175 def manage_topics_relationship(topic, registration_ids, action) body = { to: "/topics/#{topic}", registration_tokens: registration_ids } for_uri(INSTANCE_ID_API) do |connection| response = connection.post("/iid/v1:batch#{action}", body.to_json) build_response(response) end end
recover_notification_key(key_name, project_id)
click to toggle source
# File lib/fcm.rb, line 142 def recover_notification_key(key_name, project_id) params = { notification_key_name: key_name } extra_headers = { "project_id" => project_id, } for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection| response = connection.get("/gcm/notification", params) build_response(response) end end
remove_registration_ids(key_name, project_id, notification_key, registration_ids)
click to toggle source
# File lib/fcm.rb, line 125 def remove_registration_ids(key_name, project_id, notification_key, registration_ids) post_body = build_post_body(registration_ids, operation: "remove", notification_key_name: key_name, notification_key: notification_key) extra_headers = { "project_id" => project_id, } for_uri(GROUP_NOTIFICATION_BASE_URI, extra_headers) do |connection| response = connection.post("/gcm/notification", post_body.to_json) build_response(response) end end
Also aliased as: remove
send_notification(registration_ids, options = {})
click to toggle source
See developers.google.com/cloud-messaging/http for more details. { “notification”: {
"title": "Portugal vs. Denmark", "text": "5 to 1"
}, “to” : “bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1…” } fcm = FCM.new
(“API_KEY”) fcm.send(
["4sdsx", "8sdsd"], # registration_ids { "notification": { "title": "Portugal vs. Denmark", "text": "5 to 1" }, "to" : "bk3RNwTe3HdFQ3P1..." }
)
# File lib/fcm.rb, line 81 def send_notification(registration_ids, options = {}) post_body = build_post_body(registration_ids, options) for_uri(BASE_URI) do |connection| response = connection.post("/fcm/send", post_body.to_json) build_response(response, registration_ids) end end
Also aliased as: send
send_notification_v1(message)
click to toggle source
See firebase.google.com/docs/cloud-messaging/send-message {
"token": "4sdsx", "notification": { "title": "Breaking News", "body": "New news story available." }, "data": { "story_id": "story_12345" }, "android": { "notification": { "click_action": "TOP_STORY_ACTIVITY", "body": "Check out the Top Story" } }, "apns": { "payload": { "aps": { "category" : "NEW_MESSAGE_CATEGORY" } } }
} fcm = FCM.new
(api_key
, json_key_path
, project_name) fcm.send(
{ "token": "4sdsx",, "to" : "notification": {}.. }
)
# File lib/fcm.rb, line 54 def send_notification_v1(message) return if @project_base_uri.empty? post_body = { 'message': message } response = Faraday.post("#{@project_base_uri}/messages:send") do |req| req.headers["Content-Type"] = "application/json" req.headers["Authorization"] = "Bearer #{jwt_token}" req.body = post_body.to_json end build_response(response) end
Also aliased as: send_v1
send_to_topic(topic, options = {})
click to toggle source
# File lib/fcm.rb, line 184 def send_to_topic(topic, options = {}) if topic.gsub(TOPIC_REGEX, "").length == 0 send_with_notification_key("/topics/" + topic, options) end end
send_to_topic_condition(condition, options = {})
click to toggle source
# File lib/fcm.rb, line 215 def send_to_topic_condition(condition, options = {}) if validate_condition?(condition) body = { condition: condition }.merge(options) execute_notification(body) end end
send_with_notification_key(notification_key, options = {})
click to toggle source
# File lib/fcm.rb, line 155 def send_with_notification_key(notification_key, options = {}) body = { to: notification_key }.merge(options) execute_notification(body) end
subscribe_instance_id_to_topic(iid_token, topic_name)
click to toggle source
# File lib/fcm.rb, line 199 def subscribe_instance_id_to_topic(iid_token, topic_name) batch_subscribe_instance_ids_to_topic([iid_token], topic_name) end
topic_subscription(topic, registration_id)
click to toggle source
# File lib/fcm.rb, line 160 def topic_subscription(topic, registration_id) for_uri(INSTANCE_ID_API) do |connection| response = connection.post("/iid/v1/#{registration_id}/rel/topics/#{topic}") build_response(response) end end
unsubscribe_instance_id_from_topic(iid_token, topic_name)
click to toggle source
# File lib/fcm.rb, line 203 def unsubscribe_instance_id_from_topic(iid_token, topic_name) batch_unsubscribe_instance_ids_from_topic([iid_token], topic_name) end
Private Instance Methods
build_canonical_ids(body, registration_ids)
click to toggle source
# File lib/fcm.rb, line 265 def build_canonical_ids(body, registration_ids) canonical_ids = [] unless body.empty? if body["canonical_ids"] > 0 body["results"].each_with_index do |result, index| canonical_ids << { old: registration_ids[index], new: result["registration_id"] } if has_canonical_id?(result) end end end canonical_ids end
build_not_registered_ids(body, registration_id)
click to toggle source
# File lib/fcm.rb, line 277 def build_not_registered_ids(body, registration_id) not_registered_ids = [] unless body.empty? if body["failure"] > 0 body["results"].each_with_index do |result, index| not_registered_ids << registration_id[index] if is_not_registered?(result) end end end not_registered_ids end
build_post_body(registration_ids, options = {})
click to toggle source
# File lib/fcm.rb, line 239 def build_post_body(registration_ids, options = {}) ids = registration_ids.is_a?(String) ? [registration_ids] : registration_ids { registration_ids: ids }.merge(options) end
build_response(response, registration_ids = [])
click to toggle source
# File lib/fcm.rb, line 244 def build_response(response, registration_ids = []) body = response.body || {} response_hash = { body: body, headers: response.headers, status_code: response.status } case response.status when 200 response_hash[:response] = "success" body = JSON.parse(body) unless body.empty? response_hash[:canonical_ids] = build_canonical_ids(body, registration_ids) unless registration_ids.empty? response_hash[:not_registered_ids] = build_not_registered_ids(body, registration_ids) unless registration_ids.empty? when 400 response_hash[:response] = "Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields." when 401 response_hash[:response] = "There was an error authenticating the sender account." when 503 response_hash[:response] = "Server is temporarily unavailable." when 500..599 response_hash[:response] = "There was an internal error in the FCM server while trying to process the request." end response_hash end
execute_notification(body)
click to toggle source
# File lib/fcm.rb, line 289 def execute_notification(body) for_uri(BASE_URI) do |connection| response = connection.post("/fcm/send", body.to_json) build_response(response) end end
for_uri(uri, extra_headers = {}) { |connection| ... }
click to toggle source
# File lib/fcm.rb, line 224 def for_uri(uri, extra_headers = {}) connection = ::Faraday.new( url: uri, request: { timeout: DEFAULT_TIMEOUT } ) do |faraday| faraday.adapter Faraday.default_adapter faraday.headers["Content-Type"] = "application/json" faraday.headers["Authorization"] = "key=#{api_key}" extra_headers.each do |key, value| faraday.headers[key] = value end end yield connection end
has_canonical_id?(result)
click to toggle source
# File lib/fcm.rb, line 296 def has_canonical_id?(result) !result["registration_id"].nil? end
is_not_registered?(result)
click to toggle source
# File lib/fcm.rb, line 300 def is_not_registered?(result) result["error"] == "NotRegistered" end
json_key()
click to toggle source
# File lib/fcm.rb, line 331 def json_key @json_key ||= if @json_key_path.respond_to?(:read) @json_key_path else File.open(@json_key_path) end end
jwt_token()
click to toggle source
# File lib/fcm.rb, line 321 def jwt_token scope = "https://www.googleapis.com/auth/firebase.messaging" @authorizer ||= Google::Auth::ServiceAccountCredentials.make_creds( json_key_io: json_key, scope: scope, ) token = @authorizer.fetch_access_token! token["access_token"] end
validate_condition?(condition)
click to toggle source
# File lib/fcm.rb, line 304 def validate_condition?(condition) validate_condition_format?(condition) && validate_condition_topics?(condition) end
validate_condition_format?(condition)
click to toggle source
# File lib/fcm.rb, line 308 def validate_condition_format?(condition) bad_characters = condition.gsub( /(topics|in|\s|\(|\)|(&&)|[!]|(\|\|)|'([a-zA-Z0-9\-_.~%]+)')/, "" ) bad_characters.length == 0 end
validate_condition_topics?(condition)
click to toggle source
# File lib/fcm.rb, line 316 def validate_condition_topics?(condition) topics = condition.scan(/(?:^|\S|\s)'([^']*?)'(?:$|\S|\s)/).flatten topics.all? { |topic| topic.gsub(TOPIC_REGEX, "").length == 0 } end