Migrate a GCM Client App for Android to Firebase Cloud Messaging

Migrate an existing GCM client app on Android to Firebase Cloud Messaging (FCM) using the instructions in this guide.

Import your GCM project as a Firebase project

  1. In the Firebase console, select Import Google Project.

  2. Select your GCM project from the list of existing projects and select Add Firebase.

  3. In the Firebase welcome screen, select Add Firebase to your Android App.

  4. Provide your package name and SHA-1, and select Add App. A new google-services.json file for your Firebase app is downloaded.

  5. Select Continue and follow the detailed instructions for adding the Google Services plugin in Android Studio.

Switch to FCM in the app-level build.gradle

Before
dependencies {
  compile
"com.google.android.gms:play-services-gcm:8.4.0"
}
After
dependencies {
  compile
"com.google.firebase:firebase-messaging:9.0.0"
}

Remove the permissions required by GCM

All the permissions required by FCM are now added automatically by library

AndroidManifest.xml Before
<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" />
AndroidManifest.xml After
No permissions

Remove the receiver from the app manifest

With FCM, com.google.android.gms.gcm.GcmReceiver is added automatically.

AndroidManifest.xml Before
<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>
AndroidManifest.xml After
No receiver

Migrate your listener service

A service extending InstanceIDListenerService is now required only if you want to access the FCM token.

This is needed if you want to

  • Manage device tokens to send a messages to single device directly, or

  • Send messages to device group, or

  • Subscribe devices to topics with the server subscription management API.

If you don't use these features, you can completely remove this service along with client code to initiate the generation of a registration token.

Update the Android Manifest

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

Update your InstanceIDListenerService

Change MyInstanceIDListenerService to extend FirebaseInstanceIdService, and update code to listen for token updates and get the token whenever a new token is generated.

MyInstanceIDListenerService.java Before
public class MyInstanceIDListenerService extends InstanceIDListenerService {

 
...

 
@Override
 
public void onTokenRefresh() {
     
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
     
Intent intent = new Intent(this, RegistrationIntentService.class);
      startService
(intent);
 
}
}
MyInstanceIDListenerService.java After
public class MyInstanceIDListenerService extends FirebaseInstanceIdService {

 
...

 
/**
   * Called if InstanceID token is updated. This may occur if the security of
   * the previous token had been compromised. Note that this is also called
   * when the InstanceID token is initially generated, so this is where
   * you retrieve the token.
   */

 
// [START refresh_token]
 
@Override
 
public void onTokenRefresh() {
     
// Get updated InstanceID token.
     
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
     
Log.d(TAG, "Refreshed token: " + refreshedToken);
     
// TODO: Implement this method to send any registration to your app's servers.
      sendRegistrationToServer
(refreshedToken);
 
}

}

Remove registration

You no longer need to explicitly initiate the generation of a registration token — the library does this automatically. Therefore, you can remove code like the following:

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

Migrate your GcmListenerService

A service extending GcmListenerService is now required only for the following use cases:

  • receiving messages with notification payload while the application is in foreground

  • receiving messages with data payload only

  • receiving errors in case of upstream message failures.

If you don't use these features, and you only care about displaying notifications messages when the app is not in the foreground, you can completely remove this service.

Update the Android Manifest

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

Update your GcmListenerService

Change MyGcmListenerService to extend FirebaseMessagingService and update the signature of the method onMessageReceived(). This example updates the service name to MyFcmListenerService.

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

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

Update the usage of GcmPubSub

GcmPubSub methods have been integrated and simplified in the FirebaseMessaging class. To continue sending messages to your existing GCM topics, you'll need to resubscribe all devices using the new FirebaseMessaging subscribeToTopic method.

The new methods subscribeToTopic(topic-name)and unsubscribeToTopic(topic-name)include the following changes:

  • Asynchronous execution: the method doesn't block the current thread; instead, the operation is automatically performed in a background thread. You won't the need to manage threads as you did for GCM.

  • Auto retry logic: the operation is stored and automatically retried in case of connectivity issues.

  • Implicit token: the previously required token is now automatically created, using the sender ID specified by the Firebase Project.

Before
// Blocking methods. Execute them inside an AsyncTask or background thread.
GcmPubSub.getInstance(context).subscribe("token", "/topics/mytopic", null /* extras bundle */);
GcmPubSub.getInstance(context).unsubscribe("token", "/topics/mytopic");
After
// Non-blocking methods. No need to use AsyncTask or background thread.
FirebaseMessaging.getInstance().subscribeToTopic("mytopic");
FirebaseMessaging.getInstance().unsubscribeToTopic("mytopic");



http://webs.co

Update server endpoints

You can update your server code to use new FCM endpoints for sending messages via HTTP and XMPP. Note that the new FCM version of gcm-http.googleapis.com/gcm/ is fcm.googleapis.com/fcm/ (without "http"):

GCM endpointFCM endpoint
gcm-http.googleapis.com/gcm/fcm.googleapis.com/fcm/
gcm-xmpp.googleapis.comfcm-xmpp.googleapis.com

Updating these endpoints is not strictly required, as Google will continue to support the existing GCM endpoints.