Sending FCM Push Notifications with Andpush Gem
Posted on by Gentaro "hibariya" Terada
Recently, I had migrated from GCM (Google Cloud Messaging) to FCM (Firebase Cloud Messaging) because GCM was ending its life.
At first, I found fcm gem which supports FCM. I changed my application code to use the gem and I deployed the new version since it was working nicely on the staging. However, as time goes, I realized that FCM notification sometimes stops working when the application runs on multiple threads. And it’s turned out that the latest released version of fcm gem does not support multi-threaded applications as of today. That’s why I decided to use another library and that’s where Andpush gem comes into play.
Andpush gem is a fast HTTP client library for FCM. The README says it’s 3.7 times faster than fcm gem even in single-threaded environments. Thanks for net-http-persistent, it reuses HTTP connection and we can reduce extra TCP round-trip. The API is quite simple. Here is an example code from the README:
require 'andpush'
server_key = "..."
device_token = "..."
client = Andpush.new(server_key, pool_size: 25)
payload = {
to: device_token,
notification: {
title: "Update",
body: "Your weekly summary is ready"
},
data: { extra: "data" }
}
response = client.push(payload)
headers = response.headers
headers['Retry-After'] # => returns 'Retry-After'
json = response.json
json[:canonical_ids] # => 0
json[:failure] # => 0
json[:multicast_id] # => 8478364278516813477
result = json[:results].first
result[:message_id] # => "0:1489498959348701%3b8aef473b8aef47"
result[:error] # => nil, "InvalidRegistration" or something else
result[:registration_id] # => nil
Compared to fcm gem, it does not have any API to create notification key. Originally I had used this function to send a message to multiple devices. However, multicasting a message can be done by passing multiple device tokens registration_ids
: instead of passing a single device token to to:
.
--- before 2019-09-27 20:14:19.632608083 +0900
+++ after 2019-09-27 20:15:44.175032158 +0900
@@ -1,6 +1,6 @@
client = Andpush.new(server_key, pool_size: 25)
payload = {
- to: device_token,
+ registration_ids: device_tokens,
notification: {
title: "Update",
body: "Your weekly summary is ready"
Now I do not have to create notification keys.
I confirmed it works well on the staging environment. However, the app was always working fine on the staging environment even with fcm gem. I will update if I found any problems on production environment. Incidentally, this gem supports HTTP/2 experimentally. I also will report if I have time to try it.