RailsからAndroidにGCMを使って通知を送る

この記事はシス研 Advent Calendarの25日目の記事です。

思いつきで続けてしまったこの企画がここまで来るとは・・・。

巻き込まれた部員の皆さんすいませんでした。多分僕のせいです。

 

今回はプロコン等で役に立つかもしれないTipsを残しておきます。

RailsサーバからAndroidに通知を送る方法を紹介します。

 

GCMとは・・・、Google Cloud Messagingというやつです。
Androidアプリで通知を実装する上では避けて通れない仕組みです。

まずはAndroidアプリさんがGCMさんに登録してGCMさんから固有のIDをもらいます。
後は自分で作ったサーバさんからGCMさんにこのIDに通知してや〜ってお願いしてGCMさんからAndroidアプリさんに通知を送ってもらうという風な仕組みだった気がします。

 

Androidアプリ

アプリ側は↓のサイトを参考にしました。
[改訂版]Google Cloud Messaging (GCM) でプッシュ配信する[Android]

基本的にはここに書いてある通りにやっていけばいいです。

1.の補足でサーバー用のキーも取得する必要があります。許可するIPは0.0.0.0/0でも構いません。

というわけでAndroidアプリの実装は終わりです。

 

Railsサーバ

ここからが本題です。

通知を便利にするためのGemを使用します。

pushmeupというgemです。一応iOSアプリとか他の通知にも対応しているようです。

 

新しいgemをRailsアプリで使う際には例によってGemfileの最後にgem ‘pushmeup’という行を追加してbundle install。

 

次に初期設定を書きます。たったの3行!

/config/initializers/gcm.rb

GCM.host = ‘https://android.googleapis.com/gcm/send’
GCM.format = :json
GCM.key = “先ほど補足のとこで作ったサーバのAPIキー”

 

AndroidアプリがIDをRailsに登録する仕組みについてです。
ここでよくありがちなエラーがRailsは標準でCSRF対策というやつがついています。
AndroidでWebViewを用いて開発する場合は関係ありませんが、この対策によってRails外部からのPOSTリクエストが拒否されてしまいます。
この設定を解除するには

/app/controllers/application_controller.rbを編集
protect_from_forgery with: :null_session

というふうに:exceptionのところを:null_sessionと変更します。
ここだけ気をつければあとはPOSTリクエストで送って、user.registration_idなどとして保存すればOKです。

 

さあ通知を送ろう!
例えばこんなアクションで送信出来ます。

def push
  @user = User.find(params[:id])

  destination = [@user.registration_id]
  data = { message: "hello world" }

  GCM.send_notification( destination, data )

  redirect_to root_path
end

destinationが送信先のIDです。配列になってるので複数IDを指定出来ます。
dataは送るメッセージです。キーとバリューの形ですね。
GCM.send_notificationで送信しています。

 

さあ実装は完成しましたね。ところがなんとこのままローカルでは動きません
確認はできていないのですがサーバのAPIキーを作成する際に許可するIPにlocalhostが入っていないことだと考えられます。

気をとりなおしてHeroku上でサーバを動かすとちゃんと手元のAndroidアプリに通知が来るはずです。

 

本当はサンプルアプリを作りたかったけど時間が無かったのでまた後日。
一応Grouperではpushmeup使ってます。

以下おまけ

 

AndroidアプリはWebViewのみって実装の場合

Javaは書けないしAndroidアプリはWebViewのみで後は全部Railsでやるぜってアプリを作る時があると思います。絶対ある。
そんなとき、AndroidがGCMからもらったIDをどうやってWebViewの中のRailsに渡すんだ?と困った問題が発生します。

大丈夫です。ちゃんとAndroidアプリからJavaScriptを使う方法があります。
参考サイト

これを使えばちゃんとアプリからJavaScriptでhtmlの要素を操作してGCMからもらったIDを登録することが出来ます。その要素をdisplay:none;などとすれば見た目的にも問題がないわけです。

Grouperもこの方法で実装しております。

(ガチアプリを作ろうと思ったらもっとトークンとかを使って認証しっかりする必要があると思います)

 

 

RailsからAndroidアプリへの通知はプロコンでここ2年間使ったので一応ここにちゃんと残しておきます。
気が向いたら他のユーザーに通知を送るだけみたいな某サービスみたいなサンプルを作ろうと思います。

 

これでSYSKEN Advent Calendar2014おしまいです。来年はきっと無い!(適当)


コメントを残す

メールアドレスが公開されることはありません。