やりたかったこと
- cocos2d-xのアプリでバックグランド動作時にプッシュ通知を出したかった。
- 以前のWebSocketの記事で通信が来たら通知が出るイメージ
道のり
FCM(Firebase Cloud Messaging)の準備
以前はGCM(Google Cloud Messaging)と呼ばれていた物で、Android/iOS等でPush通知を行うためのプラットフォーム。
アカウント作成
下記からアカウントを作成する。
FireBase
FirebaseのプロジェクトにAndroidアプリを登録
- 登録時に必要になる下記の情報を予めメモしておく
- Androidパッケージ名
- build.gradle の applicationId で指定されているJavaパッケージ名
- デバッグ用証明書のSHA-1ハッシュ
- 下記のコマンドでJREに含まれているkeytoolから生成する
keytool -exportcert -list -v -alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore
- 各ユーザープロファイル配下のkeystoreから生成しているので、複数人で共同開発している場合はなんらかの考慮が必要…と思われる。
- Androidパッケージ名
- Firebaseのコンソール画面に移動してプロジェクトを追加する
- 「AndroidアプリにFirebaseを追加」を選択
- メモしておいた情報を入力して登録
Android Studio側での設定
設定ファイルの配置
Firebaseを利用するための設定が入った google-services.json
がダウンロード出来るようになるので、AndroidStudioの /proj.android-studio/app
へ配置する
/proj.android-studio/build.gradleの変更
buildscript {
dependencies {
// Add this line
classpath 'com.google.gms:google-services:3.2.0'
}
}
allprojects {
// ...
repositories {
// ...
maven {
url "https://maven.google.com" // Google's Maven repository
}
}
}
/proj.android-studio/app/build.gradleの変更
dependencies {
// Add this line
compile 'com.google.firebase:firebase-core:11.8.0'
compile 'com.google.firebase:firebase-messaging:11.8.0'
}
...
// Add to the bottom of the file
apply plugin: 'com.google.gms.google-services'
※Android Studio上で11.8.0ではなく15.0.0を使うように警告が出るのですが、変更するとビルド出来ない状態になりハマりました。
cocos2d-xアプリでのメッセージ購読設定
リモート通知はcocosと言うよりはAndroid側の機能なので、cppファイルではなくアプリ起動時のAppActivity.java に対してsubscribeToTopic()を追加してメッセージの購読設定をしています。
import com.google.firebase.messaging.FirebaseMessaging;
public class AppActivity extends Cocos2dxActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
…中略
// DO OTHER INITIALIZATION BELOW
FirebaseMessaging.getInstance().subscribeToTopic("news");
WebSocketサーバー側でメッセージ受信時にFCMへ送信
PHPで実装したWebSocketサーバーにFCMに対してメッセージを送信するメソッドを用意します。
クライアントからメッセージが届いた際に下記のメソッドを呼び出してFCM経由でリモート通知を送ります。
private function sendFCM($msg) {
$api_key = "API_KEY";
$base_url = "https://fcm.googleapis.com/fcm/send";
$data = array(
"to" => "/topics/news",
"priority" => "high",
"notification" => array(
"title" => "通知",
"body" => $msg
)
);
$header = array(
"Content-Type:application/json"
,"Authorization:key=".$api_key
);
$context = stream_context_create(array(
"http" => array(
'method' => 'POST'
,'header' => implode("\r\n",$header)
,'content'=> json_encode($data)
)
));
file_get_contents($base_url,false,$context);
}
※API_KEYの部分はFirebaseの「プロジェクト設定」→「クラウドメッセージング」タブに表示されている「サーバーキー」を指定します。
「プロジェクト設定」→「全般」タブの「ウェブ API キー」や、「google-services.json」に記載されている「api_key」ではないのでご注意下さい。 (自分はちょっとハマりました。)
注意点
- GenymotionではGoogle Play Serviceがインストールされておらずリモート通知が届かないようです。
- 実機もしくは公式Androidエミュレータであれば通知が届きます。