LoginSignup
41
52

More than 3 years have passed since last update.

Android Push通知 GCMからFCMに移行 #Android #Firebase

Last updated at Posted at 2017-02-08

FCMへの移行について

「FCM(Firebase Cloud Messaging)はGCMの最新バージョンです。GCMの機能を含め新機能を実装しています。新しくPush通知を実装する場合はFCMを使用し、現在GCMを使用している方はFCMに移行することを強くオススメします。」とGoogleは公言1しているので、GCMからFCMに移行しましょう。

Firebaseの準備

FCMの準備をします。まずはFirebaseの登録をしていない方はこちらを参考に登録してください。

  • FirebaseにAndroidプロジェクトを登録
  • google-services.jsonをAndroidプロジェクトに入れる
  • Firebaseのコンソールにアクセス
  • セッティングのマーク(歯車)をクリック、Project Settingに入る
  • そこにあるServer KeyServer IDをサーバー管理者に伝える

サーバーのEndpoint変更

・GCM endpoint
gcm-http.googleapis.com/gcm/
gcm-xmpp.googleapis.com

下記に変更

・FCM endpoint
fcm.googleapis.com/fcm/
fcm-xmpp.googleapis.com

これでFirebase側とサーバー側の設定は完了です。次はAndroidプロジェクト側を見ていきます。

クライアントからサーバーへの初期設定を実装

必要ライブラリをインストール

build.gradle
dependencies {
    ...
    compile 'com.google.firebase:firebase-messaging:10.0.1'
}

こちらは削除
compile "com.google.android.gms:play-services-gcm:8.4.0"

AndroidManifestの設定

下記のPermissionを削除

AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission android:name="<your-package-name>.permission.C2D_MESSAGE"
            android:protectionLevel="signature" />
<uses-permission android:name="<your-package-name>.permission.C2D_MESSAGE" />

Receiverを削除

AndroidManifest.xml
<receiver
    android:name="com.google.android.gms.gcm.GcmReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="com.example.gcm" />
    </intent-filter>
</receiver>

Serviceクラスを以下の様に書きなおす

以前の実装

AndroidManifest.xml
<service
    android:name=".MyInstanceIDListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID" />
    </intent-filter>
</service>

新しい実装

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

Serviceクラスの実装

MyInstanceIDListenerService.java
public class MyInstanceIDListenerService extends InstanceIDListenerService {
  ...
  @Override
  public void onTokenRefresh() {
      Intent intent = new Intent(this, RegistrationIntentService.class);
      startService(intent);
  }
}

このように実装していたものを下記のようにFCM用の実装に変更します。

MyInstanceIDListenerService.java

public class MyInstanceIDListenerService extends FirebaseInstanceIdService {
  ...
  @Override
  public void onTokenRefresh() {
      String refreshedToken = FirebaseInstanceId.getInstance().getToken();
      Log.d(TAG, "Refreshed token: " + refreshedToken);
      //サーバーにrefreshedTokenを送信し初期設定を行う
    //※任意メソッド
      sendRegistrationToServer(refreshedToken);
  }
}

下記のような実装は必要ないので削除

MyInstanceIDListenerService.java
 InstanceID instanceID = InstanceID.getInstance(this);
 String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
          GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
 Log.i(TAG, "GCM Registration Token: " + token);

Registration tokenを取得する方法がシンプルになりましたね。ここで取得したRegistration tokenを任意のサーバーに送信すれば初期設定完了です。

Push通知の受信を実装

AndroidManifestの設定

下記の設定を変更

以前の実装

AndroidManifest.xml
<service
    android:name=".MyGcmListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
</service>

新しい実装

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

GcmListenerServiceをFirebaseMessagingServiceに移行

MyGcmListenerService.java
public class MyGcmListenerService extends GcmListenerService {
  @Override
  public void onMessageReceived(String from, Bundle data){
    ...
  }

  ...
}
MyFcmListenerService.java
public class MyFcmListenerService extends FirebaseMessagingService {
  @Override
  public void onMessageReceived(RemoteMessage message){
    String from = message.getFrom();
    Map data = message.getData();
  }
  ...
}

これでPush通知を受け取る事ができます。
受け取ったら下記のようにNotifyを出してみましょう。

MyFcmListenerService.java

@Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        String msgBody = null;

        // TODO(developer): Handle FCM messages here.
        Log.d(TAG, "From: " + remoteMessage.getFrom());

        // Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
            msgBody = remoteMessage.getNotification().getBody();
        }

        if (msgBody != null){
            sendNotification(msgBody);
        }
    }


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

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("FCM Message")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

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

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

おまけ

GcmPubSubの使用状況を更新する

GCM
GcmPubSub.getInstance(context).subscribe("token", "/topics/mytopic", null /* extras bundle */);
GcmPubSub.getInstance(context).unsubscribe("token", "/topics/mytopic");

下記に変更

FCM
FirebaseMessaging.getInstance().subscribeToTopic("mytopic");
FirebaseMessaging.getInstance().unsubscribeToTopic("mytopic");

参考にしたサイト

Migrate a GCM Client App for Android to Firebase Cloud Messaging


41
52
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
52