buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.google.gms:google-services:4.0.2'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
Firebase Cloud Messaging in Android App using Command Pattern
Upasana | July 28, 2018 | 4 min read | 195 views
Android FCM Notification
In this tutorial we will learn how to integrate Firebase Cloud Messaging in Andorid Project using Command Design Pattern.
First of all you need to integrate Firebase Cloud Messaging in your android project, so that you are able to receive data messages into your app.
Step 1. Adding required dependencies
You need to add the below dependeices to the top level build.gradle
file.
Also, add the below dependencies to the app level build.gradle
file
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:animated-vector-drawable:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:support-compat:27.1.1'
implementation 'com.google.firebase:firebase-core:16.0.1'
implementation 'com.google.firebase:firebase-iid:16.2.0'
implementation 'com.google.firebase:firebase-messaging:17.1.0'
implementation 'com.firebase:firebase-jobdispatcher:0.8.5'
}
apply plugin: 'com.google.gms.google-services'
Step 2. Creating Command Objects for different types of messages
Now create a command interface that defines behavior when a FCM command is received. For each type of FCM message (sync, news, order_created, order_completed), an FcmCommand implementation should be provided.
public abstract class FcmCommand {
/**
* Defines behavior when FCM is received.
*/
public abstract void execute(Context context, String type, String payload);
}
The below class diagram for different command objects illustrates the use of FcmCommand for handlign different type of command messages sent by FCM:
For example, a TestCommand implementation will look like this:
public class TestCommand extends FcmCommand {
private static final String TAG = makeLogTag("TestCommand");
@Override
public void execute(Context context, String type, String payload) { (1)
LOGI(TAG, "Received FCM message: type=" + type + ", extraData=" + payload);
Gson gson = new Gson();
TestCommandModel model = gson.fromJson(payload, TestCommandModel.class);
showNotification(context, model);
}
static class TestCommandModel {
String format;
String title;
String messageBody;
}
}
1 | Each command will have a payload that can be converted into Model using Gson |
Step 3. Extend FirebaseMessagingService to receive token and message
FirebaseMessagingService
class provides two critical features - it gives us regsitration token for this user and it delivers new messages as and when they arrive.
public class MyFirebaseMsgService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
private static final String ACTION = "action";
private static final String EXTRA_DATA = "extraData";
private static final Map<String, FcmCommand> MESSAGE_RECEIVERS;
static {
// Known messages and their FCM message receivers
Map<String, FcmCommand> receivers = new HashMap<>();
receivers.put("test", new TestCommand());
// receivers.put("feed_update", new FeedCommand());
MESSAGE_RECEIVERS = Collections.unmodifiableMap(receivers);
}
/**
* Called when message is received.
*/
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
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());
// A map containing the action and extra data associated with that action.
Map<String, String> data = remoteMessage.getData();
// Handle received FCM data messages.
String action = data.get(ACTION);
String extraData = data.get(EXTRA_DATA);
LOGD(TAG, "Got FCM message, " + ACTION + "=" + action + ", " + EXTRA_DATA + "=" + extraData);
if (action == null) {
LOGE(TAG, "Message received without command action");
return;
}
//noinspection DefaultLocale
action = action.toLowerCase();
FcmCommand command = MESSAGE_RECEIVERS.get(action);
if (command == null) {
LOGE(TAG, "Unknown command received: " + action);
} else {
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
command.execute(this, action, extraData);
}
}
}
}
/**
* 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);
}
Finally, we need to register this service into AndroidManifest.xml
class, as shown below:
<service
android:name=".fcm.MyFirebaseMsgService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
At any point, if you want to get the Fcm Token from inside of your activity, then you can get it like this:
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this, new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken", newToken);
}
});
Download Source Code
You can download source code for this tutorial from my GitHub repository:
https://github.com/cancerian0684/android-firebase-messaging
References
-
Firebase Cloud Messaging Concepts - https://firebase.google.com/docs/cloud-messaging/concept-options
Top articles in this category:
- Retrofit Basic Authentication in Android
- Retrofit OAuth2 Bearer Token Authentication OkHttp Android
- Service vs Intent Service in Android
- FirebaseInstanceIdService is deprecated now
- Kotlin Coroutines with Retrofit
- iOS interview experience fresher
- iOS interview questions for 0-3 years experience