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