Android
cocos2d-x
FCM

cocos2d-xでFCMのリモート通知を受け取る

やりたかったこと

  • 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から生成しているので、複数人で共同開発している場合はなんらかの考慮が必要…と思われる。
  • 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エミュレータであれば通知が届きます。