We all want our users to stay on the latest app we release with all the bug fixes and feature enhancements. Unfortunately, not all users keep their Wi-Fi on and most of them do not have the auto-update feature of Playstore turned on. Normally, we try to put up a dismissable alert dialog asking politely to update the app but it might not go well. We would want the old users to update in a seamless way and what better than using the notification feature for sending update notifications. At the same time, we do want to send the notification to the users who are using the latest version too.

How to get it done? Follow the below steps to get it done within minutes.

Implementation Steps-

  1. Setup the Firebase Project and link it with the Android app.
  2. Add the Firebase Cloud Messaging Dependency —
implementation 'com.google.firebase:firebase-messaging:20.0.0'

3. Now, we will parse the notification a bit differently than letting Firebase handle it on its own. For doing so, in AndroidManifest.xml add the following code,

<service
    android:name=".utils.FirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

For enhanced control, you can also set the notification icon as —

<meta-data
   android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/notification_logo" />
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/notif" />

4. Create a Java class named — FirebaseMessagingService.java :

public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {

    @Override
public void onMessageReceived(RemoteMessage remoteMessage) {

if (remoteMessage.getData().size() > 0) {
int updateApp = Integer.parseInt(remoteMessage.getData().get("updateApp"));
int versionCode = Integer.parseInt(remoteMessage.getData().get("versionCode"));
String title = remoteMessage.getData().get("title");
String message = remoteMessage.getData().get("message");
if (updateApp == 1){
if (BuildConfig.VERSION_CODE < versionCode) {
                    sendUpdateApp(title, message);
                }
            }
        }
    }
}

Let me explain the code a bit here,

Firebase Cloud Messaging allows us to send the notification with some custom remote parameters. Initially, we extend the class to FirebaseMessagingService. Using the remote parameters, we can customize the notification behaviour for our users. It is a key-value pair and we will use it to parse some parameters for showing the update notification to our users.

if (remoteMessage.getData().size() > 0) {
}

The condition is used to verify that the remoteMessage is not empty and it has some data.

We have used two more parameters here —

a. updateApp — This is a check flag. If it is 1, it means the update notification has to be displayed.

b. versionCode — This is an integer value which depends on the developer. Suppose your app’s version code is 20 and you want all the users below 18 to update, you can specify it in the versionCode and only those users will get the notification.

c. Title & Message — This will be displayed as the Title and Message of the notification.

6. sendUpdateApp() function definition —

private void sendUpdateApp(String title, String body) {

    Intent sharingIntent = new Intent();
    sharingIntent.setAction(Intent.ACTION_VIEW);
    sharingIntent.setData(Uri.parse("market://details?id="+getPackageName()));

    PendingIntent sendIntent = PendingIntent.getActivity(this, 0, sharingIntent, PendingIntent.FLAG_ONE_SHOT);

    NotificationManager notificationManager =
            (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    Intent intent = new Intent(this, Main2Activity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
    Uri soundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        @SuppressLint("WrongConstant")
        NotificationChannel notificationChannel=new NotificationChannel("channel_id","channel_name",NotificationManager.IMPORTANCE_MAX);
        notificationChannel.setDescription("channel_name");
        notificationChannel.setName("channel_name");
        Objects.requireNonNull(notificationManager).createNotificationChannel(notificationChannel);
    }

    NotificationCompat.Builder notificationBuilder;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        notificationBuilder = new NotificationCompat.Builder(this,"channel_id")
                .setSmallIcon(R.drawable.notification_logo)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.notification_logo))
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(body))
                .setContentTitle(title)
                .setContentText(body)
                .addAction(R.drawable.add_icon,"Update",sendIntent)
                .setAutoCancel(true)
                .setSound(soundUri)
                .setContentIntent(pendingIntent)
                .setDefaults(Notification.DEFAULT_ALL)
                .setPriority(NotificationManager.IMPORTANCE_MAX)
                .setOnlyAlertOnce(true)
                .setChannelId("channel_id")
                .setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark));
    }
    else
    {
        notificationBuilder = new NotificationCompat.Builder(this,"channel_id")
                .setSmallIcon(R.drawable.notification_logo)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.notification_logo))
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(body))
                .setContentTitle(title)
                .setContentText(body)
                .addAction(R.drawable.add_icon,"Update",sendIntent)
                .setAutoCancel(true)
                .setSound(soundUri)
                .setContentIntent(pendingIntent)
                .setDefaults(Notification.DEFAULT_ALL)
                .setOnlyAlertOnce(true)
                .setChannelId("channel_id")
                .setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark));
    }
    if (notificationManager != null) {
        int id = (int) System.currentTimeMillis();
        notificationManager.notify(id, notificationBuilder.build());
    }
}

The function will help in generating the notification and display it to the users. Here, we use multiple things — Creating Notification Channel, setting the parameters for the notifications, setting pending intent, dispatching the notification. We have handled the cases for phones below Android Nougat and above it.

For sending out notifications like this, you can use Postman or any other you like for making an API call/Ajax request —

  1. Create a POST/ https://fcm.googleapis.com/fcm/send call request.
  2. In the Headers, add —

Content-Type : application/json

Authorization : key=??

Key is available at — Project Overview -> Project Settings -> Cloud Messaging -> Server Key.

3. Create a raw body request —

a. For sending to specific tokens —

{
“data”: {
“message”: “Please update the app to the latest version for a bug-free and enhanced experience.”,
“title”: “New Update Available!”,
“updateApp”:1,
“versionCode”:18
},
“to” : “fvOiq81ZeSk:APA91bGtiuoVTjwQ4dAupSUJvZeOBzuiDfTiRgFzMvg_-xdBSdINCQTRL-W-89LBAVhMkHnoPQ8TFg14b3vmQqrGq6BhcV1qjibV-UmrBTyaIJNsss1gRrHkxUwH4qFqiA46JujsL11j”,
“priority”: “high”
}

b. Send to a topic —

{
“condition”: “‘all’ in topics”,
“data”: {
“message”: “Please update the app to the latest version for a bug-free and enhanced experience.”,
“title”: “New Update Available!”,
“updateApp”:1,
“versionCode”:18
},
“priority”: “high”
}

Make sure you subscribe your users to a specific topic, generally you can subscribe them to topics ‘all’ for such notifications. This can be done as —

FirebaseMessaging.getInstance().subscribeToTopic("all");

Or generate the token as,

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
    @Override
    public void onSuccess(InstanceIdResult instanceIdResult) {
        String newToken = instanceIdResult.getToken();
        Log.d("TAG", newToken);
    }
});

Once done, it will look like this,

Update Notifications

I implemented update notifications feature in the One News application. One News provides short and crisp news in 60 words. Try it out here — http://bit.ly/2YPqmeF.

Leave a Reply

Your email address will not be published. Required fields are marked *