Migrating your Android App from GCM to Firebase
Introduction Google Cloud Messaging (GCM) is a free service that helps Android developers to send data from servers to their Android applications, and upstream messages back to the cloud from the user’s device. This can be a lightweight message telling the Android app that there is a new ...
Introduction
Google Cloud Messaging (GCM) is a free service that helps Android developers to send data from servers to their Android applications, and upstream messages back to the cloud from the user’s device. This can be a lightweight message telling the Android app that there is a new data to be fetched from the server or it can be a message containing up to 4kb of payload data. The GCM service handles all the aspects of queuing of messages and delivery to the target Android application running on the target device. Unveiled on June 27, 2012, at Google I/O, it was mainly aimed at providing android app support for notifications and services and for years it has been embraced by the developer community for reliable notification and trafficing.
However recently Google announced the Firebase, it target to deliver a more linear and easier implementation for your Cloud messaging and services. Coming with updates we can agree this was a good idea however it requires developers to change and update thier current project to the updates code. This article will show you how to make a easy transition from your GCM to the updated Firebase service. Since you are familiar with GCM already, i will skip the Architecture and related explanations and go straight to the point. This article will be written from a developer's perspective.
Upgrading to Firebase
Step 1
Replace your old Json file (previously generated from the server using GCM). You can replace this json file with the new file (See Image below).
Step 2
Update your graddle by removing the GCM dependency and inserting Firebase's
BEFORE
dependencies { compile "com.google.android.gms:play-services-gcm:8.4.0" }
AFTER
dependencies { compile "com.google.firebase:firebase-messaging:9.0.0" }
-- Sync Graddle
Step 3
This is my favourites in this update. Gone are those long GCM permissions required and now all it takes is fewer and cleaner lines of code.
Remove the permissions required by GCM
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" />
AFTER
No permissions Required
Step 4
Remove the receiver
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>
AFTER
No receiver Required
Step 5
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. (Discussed later below).
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.
BEFORE
<service android:name=".MyInstanceIDListenerService" android:exported="false"> <intent-filter> <action android:name="com.google.android.gms.iid.InstanceID" /> </intent-filter> </service>
AFTER
<service android:name=".MyInstanceIDListenerService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
Step 6
Update your InstanceIDListenerService
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); } }
AFTER
public class MyInstanceIDListenerService extends FirebaseInstanceIdService { ... @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); } }
Step 7
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);
Step 8
Migrate your GcmListenerService to Firebase
BEFORE
<service android:name=".MyGcmListenerService" android:exported="false"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> </intent-filter> </service>
AFTER
<service android:name=".MyFcmListenerService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Step 9
Update your GcmListenerService
BEFORE
public class MyGcmListenerService extends GcmListenerService { @Override public void onMessageReceived(String from, Bundle data){ ... } ... }
AFTER
public class MyFcmListenerService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage message){ String from = message.getFrom(); Map data = message.getData(); } ... }
It is also worth mentioning that the GcmPubSub has been updated in Firebase and now comes with two new methods subscribeToTopic(topic-name)and unsubscribeToTopic(topic-name). These new methods have some improvements such as Asynchronous execution, Auto retry logic and Implicit Token. You can esily upgrade by making little changes to your subscribeToTopic method
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");
For further study and info you can refer to the google offical webpage below
Google Official: https://developers.google.com/cloud-messaging/android/android-migrate-fcm#switch_to_fcm_in_the_app-level_buildgradle