Gcm on Rails (gcm_on_rails) is a Ruby on Rails gem that allows you to easily incorporate Google’s ‘Google Cloud Messaging for Android’ into your Rails application. This gem was derived from c2dm_on_rails (https://github.com/pimeys/c2dm_on_rails) after Google deprecated C2DM on June 27, 2012
This gem was derived from Julius de Bruijn’s gem c2dm_on_rails which according to him, was originally a rewrite of the gem
apn_on_rails written by Mark Bates and before him Fabien Penso and Sam Soffes. Thanks to all the above who were involved in
earlier versions or derivatives of the gem. I originally wanted to use the c2dm_on_rails gem for a project at Kopo Kopo, Inc
and the rug was pulled from under me when Google deprecated C2DM in favor of GCM (Google Cloud Messaging). I thus decided to
create an updated gem. This is also my first rubygem so please feel free to fix or add on anything you may see fit.
You will have to sign up to GCM first via the Google APIs Console page (https://code.google.com/apis/console).
When you create an new API project, the browser url will change to something like:
https://code.google.com/apis/console/#project:4815162342
The value after #project (4815162342) in this example is the project ID and will be used later on as the GCM sender
ID. You will also need to obtain an Api Key and for detailed instructions on how to get one, follow the instructions
here:-
http://developer.android.com/guide/google/gcm/gs.html
GCM is designed to work on Android version 2.2 or greater, so only Android 2.2> devices are eligible. The device must
also have an active Google Account if the Android version is less than version 4.1
Installation is by simply adding the following to your Gemfile:
gem 'gcm_on_rails'
The following needs to be added to your Rakefile so that you can use the the Rake tasks that ship with gcm_on_rails:
begin
require 'gcm_on_rails_tasks'
rescue MissingSourceFile => e
puts e.message
end
To create the tables needed for Gcm on Rails, run the following task:
$ rails generate gcm_migrations
Gcm on Rails like its predecessor uses the Configatron gem, http://github.com/markbates/configatron/tree/master,
Some settings need to be loaded for configuration purposes. An initialzer script that can be put in config/initializers/gcm_on_rails.rb
will suffice. Below is an example of such a script.
configatron.gcm_on_rails.api_url = 'https://android.googleapis.com/gcm/send'
configatron.gcm_on_rails.api_key = 'AAAAAAPPPPPPPIIIIIIIKKKKKEEEEYYYYY'
configatron.gcm_on_rails.app_name = 'com.yourapppackage.com'
configatron.gcm_on_rails.delivery_format = 'json'
A couple of notes:
- The api_key is the api key that you received from Google when signing up for GCM
- Note that unlike the old C2dm on Rails, GCM on Rails switches to a simple API key for authentication. ClientLogin or OAuth2 tokens will NOT work.
- The app_name is simply the name of the pacakge of your Android app.
- GCM on Rails message requests can be either be sent in plain text or JSON format. Specify ‘json’ for JSON and ‘plain_text’ for plain text format.
That’s it, you are now ready to start creating notifications.
When upgrading from version 0.1.3 to 0.1.4 you should run:
$ rails generate gcm_upgrade
When upgrading to a new version of Gcm on Rails, you should always run:
$ rails generate gcm_migrations
That way you are ensured to have the latest version of the database tables needed.
Please note that a more detailed introduction to GCM is located at http://developer.android.com/guide/google/gcm/index.html
$ rails console
>> device = Gcm::Device.create(:registration_id => "XXXXXXXXXXXXXXXXXXXXXX")
>> notification = Gcm::Notification.new
>> notification.devices << device
>> notification.collapse_key = "updates_available"
>> notification.delay_while_idle = true
>> notification.data = {:data => {:message_text => "Get on cloud nine"}}
>> notification.notification_type = "urgent"
>> notification.save
In this version you don’t have to add the registration ids of the devices you’re going to send the notifications. You just add them to notifications_devices relation by doing:
>> notification.devices << device
as it was shown in the previous example.
The following Rake task can then be used to deliver urgent notifications:
$ rake gcm:notifications:deliver["urgent"]
If you want to deliver every notification that wasn’t delivered yet:
$ rake gcm:notifications:deliver
The rake task will look for any unsent notifications in the database. If found, the notifications will then be dispatched
for delivery. If no unsent notifications exist, the Rake task simply does nothing. As described by Google, possible errors
from the GCM servers are:
Code 200 | |
Error: MissingRegistration. Happens when the request did not actually contain a registration_id parameter when in plain text format or registration_ids when in json format. | |
Error: InvalidRegistration. The registration_id passed is not on the GCM servers. The device and all of its notifications will be deleted. | |
Error: MismatchedSenderId. The sender Id that was passed is not one that the application specified as an allowed sender. | |
Error: NotRegistered. An existing registration Id has ceased to be valid. The device and all of tis notifications will be deleted. | |
Error: MessageTooBig. The total payload data that is in the message exceeds 4096 bytes. |
Code 401 | |
API Key is Invalid. Check the configuration file |
Code 503 | |
Service is unavailable and you should retry later. However, you must honor the ‘Retry-After’ header if it is included in the response from the GCM server. Exponential backoff should be implemented in your retry mechanism. |
Code 500 | |
Internal server error. Retry again while still honoring ‘Retry-After’ header and using exponential backoff. |
- For some reason Gcm servers sometimes return a status code 200 with a nil ‘message’ key in the json returned but the
message is still sent successfully. For version 0.1.3 a nil check has been introduced to check if the message key in the json
is nil. The issue that still exists, is that if the message is nil we have no way of knowing if the message was successfully sent
just by going by the http status code 200 because HTTP status code 200 could still mean that the errors mentioned above could have
occurred. So I still consider this as temporary ‘hack’ until someone figures out why the Gcm servers may be sometimes sending nil
in the message object of the return json.
- Tests, tests then some more tests. These need to be implemented.
- Implement some sort of mechanism to update from previous versions
Released under the MIT license.
Copyright © 2012 Dennis Ondeng. See LICENSE.txt for further details.