Java
Android
GCM
Firebase
FCM

【Android】まだやってない人のためのGCMからFCMへの移行作業まとめ

Android、GCMからFCMへの移行

Googleでは2018年4月10日よりGCMを非推奨としています。GCMサーバーとクライアントAPIは非推奨となり、2019年4月11日に削除されることになっています。

FCMはもっとクールで最高なサービスです、移行しましょう👍

GCMからFCMへの移行に際して対応内容をまとめました、ご参考になれば
幸いです。

Firebase Console でプロジェクトの登録

  • firebase consoleでプロジェクト作成しAndroidのプロジェクトでfirebase導入の設定を行う

①Firebaseコンソールで、[プロジェクトの追加]を選択します。
②既存のGoogle CloudプロジェクトのリストからGCMプロジェクトを選択し、[Add Firebase]を選択します。
③Firebaseのようこそ画面で、Android AppにFirebaseを追加を選択します。
④パッケージ名とSHA-1を入力し、[アプリケーションの追加]を選択します。 Firebaseアプリ用の新しいgoogle-services.jsonファイルがダウンロードされます。
⑤[続行]を選択し、AndroidStudioでGoogleサービスプラグインを追加し(firebaseで表示されいる)手順に従います。

Migrate a GCM Client App for Android to Firebase Cloud Messaging

gradleの修正

削除

dependencies {
  compile "com.google.android.gms:play-services-gcm:15.0.1"
}

追加

dependencies {
  compile "com.google.firebase:firebase-messaging:17.3.0"
}

AndroidMAnifest.xmlの修正

パーミッション削除

FCM SDKによって、必要なものはパーミッション設定を含め、自動的に追加されます。明示的に設定し重複することを避けるため、削除します。

また、GcmReceiverが不要になるため削除します。

以下に相当する箇所を削除します。

<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
    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>

GcmListenerServiceの記述を修正

変更前

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

変更後

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



補足

android:exported

アクティビティを他のアプリのコンポーネントから起動できるかどうか。起動できる場合は "true"、起動できない場合は "false" を設定します。"false" の場合、同じアプリまたは同じユーザー ID を持つアプリのコンポーネントからのみアクティビティを起動できます。

Android Developer

関連クラスの実装・修正

GCMReceiverService.java の継承元を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();
  }
  ...
}

トークン取得処理周りの実装をしている場合

FirebaseMessagingServiceにonNewTokenメソッドがあるのでそれを使用します。
FirebaseMessagingServiceを継承したクラスでonNewTokenメソッドをオーバーライドすることで対応できます。

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onNewToken(token: String?) {
        // tokenを使用した処理
    }
}

FirebaseInstanceIdServiceがDeprecatedになった件

StackOverFlow FirebaseInstanceIdService is deprecated

トークンが生成される際の処理ですが、以前はFirebaseInstanceIdServiceクラス内にて対応していました。

しかし、firebase-messaging:17.1.0からFirebaseInstanceIdServiceがdeprecatedになっているため現状は上記のような実装になっています。

This class was deprecated.
In favour of overriding onNewToken in FirebaseMessagingService. Once that has been implemented, this service can be safely removed.

FirebaseInstanceIdServiceに関する公式ドキュメント

また、登録処理は不要になります

明示的に登録トークンの生成を開始する必要はなくなりました。ライブラリが自動的に行ってくれます。したがって、次のようなコードも削除することができます。

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

また、現在のトークンを取得する際は以下のようにして取得することができます。

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( new OnSuccessListener<InstanceIdResult>() {
            @Override
            public void onSuccess(InstanceIdResult instanceIdResult) {
                String deviceToken = instanceIdResult.getToken();
                Log.d("test", "現在の token: " + deviceToken);
            }
        });

What to use now that FirebaseInstanceId.getInstance().getToken() is deprecated [duplicate]

バックエンド側

  • サーバーのEndpoint変更

【GCM Endpoint】
gcm-http.googleapis.com/gcm/
gcm-xmpp.googleapis.com

これらを下記に変更します

【FCM Endpoint】
fcm.googleapis.com/fcm/
fcm-xmpp.googleapis.com

参考