Firebase Cloud Messaging
FCM is the new version of GCM under the Firebase brand. It inherits GCM’s core infrastructure, with new SDKs to make Cloud Messaging development easier.
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost. A message can transfer a payload of up to 4KB to a client app.
The above 1.1 and 1.2 simple images describes how FCM works.
Set up Firebase and the FCM SDK
- If you haven’t already created project , then add Firebase to your Android project.
- In Android Studio, add the FCM dependency to your app-level build.gradle file:
implementation ‘com.google.firebase:firebase-messaging:17.3.4’
Edit your app manifest
A service that extends FirebaseMessagingService.This is required if you want to do any message handling beyond receiving notifications on apps in the background.
<service android:name=".java.AppFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Accessing Device Registration Token
On initial startup of your app, the FCM SDK generates a registration token for the client app instance. This token will be received in override method onNewToken of FirebaseMessagingService class.
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
@Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token);
}
The registration token may change
- When app deletes Instance ID
- When app is restored on a new device
- When user re-installs or uninstalls the app
- When user deletes the app data
Retrieve The Current Registration Token
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
@Override
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
}
});
Receive FCM Message
/**
* Called when message is received.
*
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//check for the data/notification entry from the payload
}
If we need to do some logic with received notification (i.e get the message details and locally save them in a database) or change the UI (use a larger icon or change the status bar icon) of the notification in the onMessageReceived method from the class which extends from FirebaseMessagingService is the place we need to do it.
Firebase Message Types :
- Notification payload
- Data Payload
- Both Notification and Data Payload
There is a difference between notification payload and data payload.
Our app will react differently when it gets a notification payload or data payload.
1. Notification Payload
By sending this kind of messages, you won’t get much control over the notification. The notification will be shown automatically when the app is in background.
- Main json object is “notification”
- Display notification automatically when the app is in the background
- Predefined key values (“body”)
- App in the background: shows notification
- App in the foreground: triggers onMessageReceived()
2. Data Payload :
Data messages has to be handled by the android app. You can add this kind of messages if you want to send some additional data along with the notification
- Main json object is “data”
- Requires you to do all the data processing
- All custom key value pairs
- App in foreground or background triggers onMessageReceived()
3. Both Notification and Data Payload :
A message can also contains both notification and data payload. When these kind of messages are sent, it will be handled in two scenarios depending upon app state (background / foreground). For these message we can use both notification and data keys.
- Behave like a notification message
- App in the background: shows notification, does not trigger onMessageReceived(), the notification has extras in the intent
- App in the foreground: triggers onMessageReceived()
Message Targeting Types :
- Topic Message : Subscription of topic can send message to all subscribed users. Topics are like mailing lists. Some client devices will choose to subscribe to a topic, and then only those devices which subscribed will be sent the messages when the topic sends a message.
Subscribe Topic :
FirebaseMessaging.getInstance().subscribeToTopic("TopicName");UnSubscribe Topic : FirebaseMessaging.getInstance().unsubscribeFromTopic("TopicName");
2. Upstream Message : The Client App is sending a message towards your App Server.
/**
*SENDER_ID - A unique numerical value created when you create
*your Firebase project,available in Firebase Console.
*Message Id - ID of the message. It must be unique for all *messages.
*Data - The message data comprising the key-value pairs of the *message's payload.
*/FirebaseMessaging fm = FirebaseMessaging.getInstance();
fm.send(new RemoteMessage.Builder(SENDER_ID + "@gcm.googleapis.com")
.setMessageId(Integer.toString(messageId))
.addData("my_message", "Hello World")
.addData("my_action","SAY_HELLO")
.build());
3. Device Groups : Send token ids to fcm with key will add token to groups,max id 20. A sets of devices that all belong to the same user (ex: 2 phones and a tablet with the same app). We can store sets of devices together in a device group. The creation and management of these device groups is done all in the server side on the app server.