概要
GoogleのFCMサービスを用いてAndroid端末にメッセージを送信する。
HTTP v1に対応したサーバーAPIを用いてメッセージを送信し、Android端末でPush通知を受け取ることが出来るようにする。
準備
Firebase Consoleのアカウントを用意し、ログインする。
プロジェクト名を入力(任意の名前)
アナリティクスと課金の地域:日本
プロジェクトを作成を押下
証明書の発行とSHA-1キーの取得
keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore
パスワードの入力を求められます。
android
で発行できました。
デバッグ用の署名証明書 SHA-1(省略可)に、debug.keystoreを発行した際にコンソールで出力されたSHA-1キーをそのまま貼り付ける。
アプリを登録を押下。
Android Studioで新規プロジェクトを作成(Empty Activity)
google-services.jsonをダウンロードすし、Android Studioのapp直下に配置する。
AndroidManifest.xmlに下記のサービスを追記。
<service
android:name="com.example.shosakaguchi.notifytest.FcmMessagingService"
>
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name="com.example.shosakaguchi.notifytest.FcmInstanceIdService"
>
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
アプリのbuild.gradleに下記の依存関係を追加。
api 'com.google.firebase:firebase-core:+'
api 'com.google.firebase:firebase-messaging:+'
api 'com.fasterxml.jackson.core:jackson-databind:+'
api 'com.google.firebase:firebase-auth:+'
プロジェクトのbuild.gradleに下記の依存関係を追加+google-servicesを適用。
dependencies {
api "com.google.firebase:firebase-messaging:10.2.4"
}
apply plugin: 'com.google.gms.google-services'
プロジェクトのRebuildをする。
Android Studioで下記のクラスを生成する。
FirebaseMessagingServiceを継承したクラス(中身は空でOK)
任意のクラス名 extends FirebaseMessagingService
FirebaseInstanceIdServiceを継承したクラス
任意のクラス名 extends FirebaseInstanceIdService
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
}
MainActivity.javaにトークンを端末トークンを取得するコードを追加。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get device token
FcmInstanceIdService sv = new FcmInstanceIdService();
sv.onTokenRefresh();
}
}
プロジェクトを、プッシュ通知受け取る端末でRunする。
Android Studio上のLogcatコンソールに出てきたトークンを控える。
サーバーAPIの実装(Spring boot)
Eclipse上でSTSを用い、Spring Projectを新規作成する。
build.gradleに下記の依存関係を追加する。
compile('com.fasterxml.jackson.core:jackson-databind:+')
compile('com.google.firebase:firebase-admin:+')
Gradleタスクから、buildDependentsを叩く。
下記の情報をFirabaseコンソールページの設定ページから準備する。
・POST送信先のエンドポイントURL
https://fcm.googleapis.com/v1/projects/全般ページのプロジェクトID/messages:send"
・秘密鍵
Firabaseコンソールの設定ページからサービスアカウントをクリック
Firebase Admin SDKタブの「新しい秘密鍵の生成」を押下。
ほにゃらら.jsonがダウンロードされるので、Springプロジェクトの適当なリソースフォルダに配置しておく。
initializeメソッドの実装
public static void initializeToken() throws IOException{
FileInputStream serviceAccount = new FileInputStream("ダウンロードした秘密鍵のパス");
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("https://プロジェクトID.firebaseio.com")
.build();
FirebaseApp.initializeApp(options);
}
アクセストークン取得メソッドの実装
public static String getAccessToken() throws IOException {
GoogleCredential googleCredential = GoogleCredential
.fromStream(new FileInputStream("ダウンロードした秘密鍵のパス"))
.createScoped(Arrays.asList("https://www.googleapis.com/auth/firebase.messaging"
));
googleCredential.refreshToken();
return googleCredential.getAccessToken();
}
とりあえずサーバーアプリを実行したらメッセージを送信するようにするため、mainクラスに処理をべたがきする
TestProject.java
public static void main(String[] args) {
SpringApplication.run(PushAppTestApplication.class, args);
System.out.println("start");
try {
//initialize firebasio
initializeToken();
//post param create
URL url = new URL(POST送信先のエンドポイントURL);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Authorization", "Bearer " + getAccessToken());
// System.out.println("token" + getAccessToken());
httpURLConnection.setRequestProperty("Content-Type", "application/json; UTF-8");
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
OutputStream out = httpURLConnection.getOutputStream();
PrintStream ps = new PrintStream(out);
ps.print(リクエストメッセージJSONのBODY部(後述));
ps.close();
//return response output
InputStream is = httpURLConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String s;
while ((s = reader.readLine()) != null) {
System.out.println(httpURLConnection.getResponseMessage() + httpURLConnection.getResponseCode());
}
reader.close();
httpURLConnection.disconnect();
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("end");
}
リクエストメッセージJSONのBODY部
private final static String reqJson = "{\n" +
" \"message\":{\n" +
" \"token\" : \"Android Studio上のLogcatコンソールに出てきたトークン",\n" +
" \"notification\" : {\n" +
" \"body\" : \"テストメッセージ\",\n" +
" \"title\" : \"テストタイトル\",\n" +
" }\n" +
" }\n" +
"}";
実装は以上。
今回は単一の端末にPush通知を送信することを主に実装しました。
実務では、複数の端末に送る場合の想定や、送信時間の想定(cronバッチなど)、デバイストークンをサーバに送信する仕組みやそれを保管することなど、密に考える必要がります。
次回以降、それらのHowToや事例を紹介したいと考えてます。
お疲れ様でした。