0

When my app receives a notification with a data payload, it arrives in the system tray and I can click the notification to receive the data in my launcher activity, which I can then pass on to my Fragment:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {   
        // Notification data
        val user2 = intent?.extras?.getString("user2")
        val intent = Intent(this, HomeActivity::class.java)
        intent.putExtra("user2", user2)
        startActivity(intent)
        return finish()

My Firebase Cloud Message uses both Notification and Data

However, if a notification comes through and the user opens the app without clicking on the notification, it bypasses MainActivity and goes directly to the Fragment. This means I can't intercept the intent data from the notification.

Is there another way I can access the notification data from my Fragment?

Zorgan
  • 8,227
  • 23
  • 106
  • 207
  • read [this](https://guides.codepath.com/android/communicating-with-an-event-bus) or if you want to use default just use [LocalBroadcastReceiver](https://stackoverflow.com/questions/8802157/how-to-use-localbroadcastmanager) when your app receive message from FCM – shadow Jan 03 '20 at 07:52
  • `LocalBroadcastReceiver` is currently deprecated: https://developer.android.com/reference/androidx/localbroadcastmanager/content/LocalBroadcastManager.html?hl=en – Zorgan Jan 03 '20 at 08:08
  • the first link is eventbus bro :) – shadow Jan 03 '20 at 08:09
  • as i mention,if you want to use default -> localbroadcast or else use eventbus.EventBus is freakin ez-er and useful :D – shadow Jan 03 '20 at 08:10
  • Thankyou I'll have a look. On first glance the only thing putting me off with Eventbus is having to maintain the lifecycle – Zorgan Jan 03 '20 at 08:10
  • it's all in the document,pretty simple to maintain i think :D – shadow Jan 03 '20 at 08:12
  • Hi, you mean to say when user opens the app clicking on launcher icon and not on notification, but u want to access the notification data in fragment? – ked Jan 03 '20 at 08:20
  • That is correct @ked – Zorgan Jan 03 '20 at 08:21
  • @Zorgan, can you add the payload you are trying to send from firebase? It is possible to ensure that onMessageReceived is always called by sending a data only payload(no notification). – Derryl Thomas Jan 03 '20 at 09:59

1 Answers1

1

One solution is to store the data in shared preference or sqlite db depending on your requirment, in onMessageReceived, and if you want onMessageRecieved irrespective of app is in foreground or backgroun, then instead of sending notification message too user always send data message to user and show show notification using NotificationBuilder instead of default FCM notification, this way you'll always have data in local persistence.

override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val sp = applicationContext.getSharedPreferences("NOTIFICATION_SHARED_PREFERENCE",Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.putString("data",remoteMessage.data.toString())
        editor.commit()

        val pendingIntent:PendingIntent = PendingIntent.getActivity(this,Random().nextInt(),intent,0)
        showNotification(remoteMessage.data["title"]!!,remoteMessage.data["body"]!!,pendingIntent)
}

    private fun showNotification(title:String,description: String,pendingIntent: PendingIntent){
        val icon =  R.drawable.ic_notification
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(icon)
            .setContentTitle(title)
            .setContentText(description)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setGroup(GROUP_KEY_PUSH_MESSAGES)
            .setContentIntent(pendingIntent)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .setAutoCancel(true)
            .build()


        NotificationManagerCompat.from(applicationContext).apply {
            notify(Random().nextInt(),notification)
        }
    }

and you can access the data directly in fragment using following method, no need to pass data to fragment from activity.


            val sp = applicationContext.getSharedPreferences("NOTIFICATION_SHARED_PREFERENCE",Context.MODE_PRIVATE)
            val type = object : TypeToken<HashMap<String,String>>() {}.type
            val data:HashMap<String,String> = Gson().fromJson(sp.getString("data",""),type)
            intent.putExtra("user2",data["user2"])//use the prefered key

ked
  • 2,426
  • 21
  • 24
  • `onMessageReceived()` does not get called when notification contains data and is in the background. There is also no way to access the intent extras of `MainActivity` from my Fragment – Zorgan Jan 03 '20 at 08:44
  • i have updated the answer please check, you need to change little bit of your backend as well. and you can always access activity intent extras from fragment as following activity.intent.extras – ked Jan 03 '20 at 09:13
  • Thankyou @ked that method works. Is it also viable to send 2 messages: 1 data message and 1 notification message at the same time? – Zorgan Jan 03 '20 at 10:35
  • 1
    yup, you can send both message separately at the same time, and you don't have to show notification in onMessageRecieved(), as firebase will take care of showing notification for you, and your data message will be also saved in local persistence – ked Jan 03 '20 at 10:42