Ahmad Naser Turnkey Ecosystem Ahmad Naser
May 12, 2018

FirebaseService, onMessageReceived, FirebaseInstanceIdService, onTokenRefresh, sendRegistrationToServer

Published in the Ahmad Naser ecosystem. Estimated reading time: 5 minutes.

This is a real demenostration of how to use Android Studio with kotlin and wordpress to implement push notification using FirebaseService, onMessageReceived, FirebaseInstanceIdService, onTokenRefresh, sendRegistrationToServer

Folowing up with the previous article is required:
https://ahmadnaser.com/android-wordpress-blog-project-kotlin-volley-retrofit2-gson-okhttp-picasso-ahbottomnavigation/

Then you will be ready to proceed with this step by reserving yours gbeapis
1-reserve your WordPress hosting from greenbackend and get your wordpress greenbackend api license
http://greenbackend.com/developer-hosting

 

2-ADD the following permissoins and services to the manifest

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
     <service
            android:name=".Services.GreenFirebaseService"
        android:enabled="true"
        android:exported="true"
            >
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />

            </intent-filter>

        </service>
        <service
            android:name=".Services.FirebaseInstanceIDService"
            android:enabled="true"
            android:exported="true"
            >
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>

3- FirebaseInstanceIDService

package com.ahmadnaser.gbeapiswpblogdemo.Services

import android.util.Log

import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.iid.FirebaseInstanceIdService
import com.google.firebase.messaging.FirebaseMessaging


class FirebaseInstanceIDService  : FirebaseInstanceIdService() {

    val TAG = FirebaseInstanceIDService::class.java.simpleName!!


    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "onCreate contact firebase instance service");
    }

    override fun onTokenRefresh() {
        Log.d(TAG, "onTokenRefresh")
        val refreshedToken = FirebaseInstanceId.getInstance().token
        // we want to send messages to this application instance and manage this apps subscriptions on the server side
        // so now send the Instance ID token to the app server
        refreshedToken?.let {
            sendRegistrationToServer(it)
        }
    }

    companion object {
        const val TAG = "GibbyInstanceIdService"
    }


    private fun sendRegistrationToServer(refreshedToken: String) {
        Log.d(TAG, "Refreshed token: $refreshedToken - send this to server?")
        FirebaseMessaging.getInstance().subscribeToTopic("global")
    }

}

4- GreenFirebaseService

package com.ahmadnaser.gbeapiswpblogdemo.Services

import android.app.Notification
import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import android.content.Context.NOTIFICATION_SERVICE
import android.app.NotificationManager
import android.graphics.BitmapFactory
import com.ahmadnaser.gbeapiswpblogdemo.R.mipmap.ic_launcher
import android.app.PendingIntent
import android.content.Context
import com.ahmadnaser.gbeapiswpblogdemo.MainActivity
import android.media.RingtoneManager
import android.support.v4.app.NotificationCompat
import android.support.v4.app.TaskStackBuilder
import android.text.Html
import com.ahmadnaser.gbeapiswpblogdemo.Activities.PostDetailsActivity
import com.ahmadnaser.gbeapiswpblogdemo.Fragments.HomeViewModel
import com.ahmadnaser.gbeapiswpblogdemo.R


class GreenFirebaseService : FirebaseMessagingService() {

    val TAG = "GreenFirebaseService"


    override fun onMessageReceived(remoteMessage: RemoteMessage?) {
        // [START_EXCLUDE]
        // There are two types of messages data messages and notification messages. Data messages are handled
        // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
        // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
        // is in the foreground. When the app is in the background an automatically generated notification is displayed.
        // When the user taps on the notification they are returned to the app. Messages containing both notification
        // and data payloads are treated as notification messages. The Firebase console always sends notification
        // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
        // [END_EXCLUDE]

        // TODO(developer): Handle FCM messages here.
        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ
        Log.d(TAG, "From: " + remoteMessage!!.from!!)

        // Check if message contains a data payload.
        if (remoteMessage.data.size > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.data)
        }

        //remoteMessage.getData().containsKey("post_id");

        // Check if message contains a notification payload.
        if (remoteMessage.notification != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.notification!!.body!!)
            sendNotification(remoteMessage.notification!!.title, remoteMessage.notification!!.body, remoteMessage.data)
        }

        if (remoteMessage.notification == null && remoteMessage.data.size > 0) {
            sendDataNotification(remoteMessage.data)
        }

        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
    }
    // [END receive_message]

    private fun sendNotification(title: String?, messageBody: String?, data: Map<String, String>) {

        var intent = Intent(this, MainActivity::class.java)
        if (data.size > 0 && data.containsKey("post_id")) {
            intent = Intent(this, PostDetailsActivity::class.java)
            intent.putExtra(HomeViewModel.POST_ID, data["post_id"])
            intent.putExtra(HomeViewModel.POST_NAME, data["post_title"])
            intent.putExtra(HomeViewModel.POST_AUTHOR,data["post_date"])
            intent.putExtra(HomeViewModel.POST_IMAGE,data["post_image"])



        }
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT)

        val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder = NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_home_black_48dp)
                .setContentTitle(title)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent)

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        //notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }


    private fun sendDataNotification(data: Map<String, String>) {
        val stackBuilder = TaskStackBuilder.create(this)

        val num = System.currentTimeMillis().toInt()

        if (data.size > 0) {
            var intent = Intent(this, MainActivity::class.java)
            if (data.containsKey("post_id")) {
                intent = Intent(this, PostDetailsActivity::class.java)
                intent.putExtra(HomeViewModel.POST_ID, data["post_id"])
                intent.putExtra(HomeViewModel.POST_NAME, data["post_title"])
                intent.putExtra(HomeViewModel.POST_AUTHOR,data["post_date"])
                intent.putExtra(HomeViewModel.POST_IMAGE,data["post_image"])
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
                stackBuilder.addParentStack(MainActivity::class.java)
            } else {
                //if there is splash screen load it
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                stackBuilder.addParentStack(MainActivity::class.java)
            }
            stackBuilder.addNextIntentWithParentStack(intent)


            //PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
            val pendingIntent = stackBuilder.getPendingIntent(num, PendingIntent.FLAG_ONE_SHOT)

            val title =  Html.fromHtml(data["title"]).toString()
            val messageBody =  Html.fromHtml(data["message"]).toString()

            //Notification Builder
            val mBuilder = NotificationCompat.Builder(
                    applicationContext).setAutoCancel(true)
                    .setDefaults(Notification.DEFAULT_ALL)
                    .setContentTitle(title)
                    .setSmallIcon(R.drawable.ic_home_black_48dp)
                    .setLargeIcon(BitmapFactory.decodeResource(applicationContext.resources, R.drawable.ic_list_black_48dp))
                    .setContentText(messageBody)

            val bigText = NotificationCompat.BigTextStyle()
            bigText.bigText(messageBody)
            bigText.setBigContentTitle(title)
            bigText.setSummaryText(title)

            mBuilder.setStyle(bigText)
            mBuilder.setPriority(NotificationCompat.PRIORITY_MAX)

            mBuilder.setContentIntent(pendingIntent)

            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

            notificationManager.notify(num /* ID of notification */, mBuilder.build())
        }
    }
}

Leave a Reply

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