Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
230
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@flatfisher

AndroidのPush通知(FCM)をサーバー知識無しで試してみよう

AndroidのPush通知を試してみよう

AndroidのPush通知って難しそうなイメージがありますよね。最近はFirebaseなどのmBaaSがあるので比較的簡単になってきました。しかし本来どのようにPush通知を送るのか、Firebaseなどではなく自分のサーバーからPush通知をどのような方法で出したらいいのか分からない方がいると思います。そこで今回はPush通知の出し方を簡単に紹介したいと思います。

この記事について

対象者

  • Push通知の仕組みを知りたい
  • 普段モバイルアプリを開発している
  • サーバーはあまり得意ではない
  • Firebaseもいいが、いつかは自分のサーバーやmBaaS以外のサーバーからPush通知を送りたい

Push通知の大体の仕組み

  1. Firebaseから固有IDを振ってもらう
  2. そのIDをサーバー管理者に伝える
  3. サーバーがFirebaseに対して、このIDに通知を出してくれとお願いする
  4. FirebaseがAndroid端末にPush通知を発行する

Screen Shot 0029-05-10 at 18.27.03.png

今からやるならGCMではなくFCMを使おう

こちらにも書いてありますが、これからのPush通知はGCMではなくFCMを使用することを強く推奨しています。

今後のGCMについて

2019年4月11日にGCMは使えなくなるみたいなので、GCMを使っている人は移行しましょう。

GCM APIを使用するプロジェクトをご利用の場合は、2019年4月11日より前にクライアントとサーバーのコードをFCMを使うように変更する必要があります。既存のGCMトークンはFCMで引き続き使用でき、既存のユーザーに送信する機能は失われません。

if you have projects that are still using the GCM APIs, you will need to update your client and server code to use FCM before April 11, 2019. Your existing GCM tokens will continue to work with FCM so you won’t lose the ability to send to your existing users.

実装の流れ

  1. Firebaseの導入
  2. Androidプロジェクトのコードを準備
  3. アプリを実行してInstanceIDを取得する
  4. PostmanでFCMサーバーにデータを投げる

Firebase導入

  1. 新規プロジェクトの作成
  2. google-services.jsonをダウンロード

新規プロジェクトの作成

Firebaseにログイン
コンソールに行くと「新規プロジェクトの作成」と「Googleプロジェクトをインポート」がある。

既にGoogle Maps APIやGAEなどを使用しており、同じプロジェクトにFirebaseを入れたい人はインポートを選ぶ。

新規プロジェクトを作成した後は、[AndroidアプリにFirebaseを追加]を選択

Screen Shot 0028-11-24 at 11.16.25.png

すると以下のような画面がでてきます。

Screen Shot 0028-11-24 at 11.23.19.png

必要な情報を入力しましょう。
デバッグ用のkeystoreは以下のようなコードで取得可能です。

Mac/Linux
keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore
Windows
keytool -exportcert -list -v \
-alias androiddebugkey -keystore %USERPROFILE%\.android\debug.keystore

google-services.json のインポート

アプリを作成すると、google-services.jsonが生成され自動的にダウンロードされます。
こちらのファイルをAndroidプロジェクトのappの配下に入れましょう。

Androidプロジェクトのコードを準備

プロジェクトレベルのbuild.gradleに以下を追加

build.gradle
buildscript {
  dependencies {
    // ここに追加
    classpath 'com.google.gms:google-services:3.0.0'
  }
}

アプリレベルのbuild.gradleに以下を追加

build.gradle
dependencies {
  compile "com.google.firebase:firebase-messaging:10.2.4"
}

// ファイルの一番下に追加
apply plugin: 'com.google.gms.google-services'

apply plugin: 'com.google.gms.google-services'はファイルの一番下に設置してください。

Push通知に使用するIDを取得するためのMyInstanceIDListenerServiceクラスを作成

こちらのIDはPush通知に使用するのでサーバー管理者に送信する。しかし今回はサーバーを使用しないのでサーバー管理者にIDを送信する処理は省略する。

MyInstanceIDListenerService.java

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

public class MyInstanceIDListenerService extends FirebaseInstanceIdService {

    private static final String TAG = MyInstanceIDListenerService.class.getSimpleName();

    @Override
    public void onTokenRefresh() {
        //ここで取得したInstanceIDをサーバー管理者に伝える

        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);
    }
}

AndroidManifestにMyInstanceIDListenerServiceを追加

AndroidManifest.xml
<application>
   <service
      android:name=".MyInstanceIDListenerService">
      <intent-filter>
          <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
      </intent-filter>
   </service>
<application/>

Push通知を受け取るレシーバークラスを作成

ここで受け取った内容を通知する処理も追加します。

MyFcmListenerService.java
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;

public class MyFcmListenerService extends FirebaseMessagingService {

    private final static String TAG = MyFcmListenerService.class.getSimpleName();

    @Override
    public void onMessageReceived(RemoteMessage message){
        String from = message.getFrom();
        Map data = message.getData();

        Log.d(TAG, "from:" + from);
        Log.d(TAG, "data:" + data.toString());

        String msg = data.get("data").toString();
        sendNotification(msg);
    }

    private void sendNotification(String message) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,0 , intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Push通知のタイトル")
                .setSubText("Push通知のサブタイトル")
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(message))
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 , notificationBuilder.build());
    }
}

AndroidManifestにMyFcmListenerServiceを追加

AndroidManifest.xml
<application>
   <service
       android:name=".MyFcmListenerService">
       <intent-filter>
           <action android:name="com.google.firebase.MESSAGING_EVENT" />
       </intent-filter>
   </service>
<application/>

Push通知を購読or解除

最後にこちらのメソッドを実行すればPush通知の購読or解除が可能です。

MainActivity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.google.firebase.messaging.FirebaseMessaging;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Push通知の購読開始
        FirebaseMessaging.getInstance().subscribeToTopic("mytopic");

        //購読解除
        FirebaseMessaging.getInstance().unsubscribeFromTopic("mytopic");
    }
}

アプリを実行してInstanceIDを取得する

アプリを実行してInstanceIDを取得しそのIDをメモしておいてください。
LogcatにIDが表示されるはずです。

Logcat
MyInstanceIDListenerService: Refreshed token: xxxxxxxxxxxxxxxxxxxxx

Postmanに必要情報を入力する

本来はサーバーからPush通知を送信しますが、今回は手動で送信したいと思います。送信にはHTTPリクエストを簡単作れる、GoogleChromeExtensionの Postman を使いたいと思います。
Postmanについてはこちらを参照ください。

サーバーキーを取得しよう

Firebaseコンソールのクラウドメッセージングという項目からサーバーキーをメモしておいてください。

Screen Shot 0029-05-10 at 17.31.31.png

PostmanからPush通知!!

Postmanに必要情報を入れる

1.Postmanのリクエスト方法を「Post」にする
2.URLに https://fcm.googleapis.com/fcm/sendを入力
3.HeadersのKeyに AuthorizationContent-Typeを追加
4.HeadersのValueにkey=サーバーキーapplication/jsonを入力

※サーバーキーは先ほどFirebaseのコンソールで取得したものを入れてください。

Screen Shot 0029-05-10 at 17.36.48.png

5.BodyのrawにJson形式のテキストを作ってください。
6.idに先ほどLogcatで取得したトークンを入れてください。

Screen Shot 0029-05-10 at 17.58.35.png

Push通知を送信する

ここまで入力が終えたら終了です。Sendボタンを押してPush通知を試してみてください。以下の様にAndroidに通知が表示されれば成功です。

Android

※送信時点でエラーが起きるとPostmanにエラーが返ってきます。

Push通知の大体の仕組みを見ていただきました。あとはPostmanでやっている処理をサーバーに実装するだけでサーバーからPush通知を作成することができます。Push通知を活用して1ランク上の開発にトライしてみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
230
Help us understand the problem. What are the problem?