androidandroid-intentandroid-emulatorandroid-pendingintent

Android intent extras values not changing with new data on MainActivity


I am using FCM to send a notification to my Android app which is received and processed by my FirebaseMessagingService. That works fine. I take the information from the FCM notification and pass it to a function (inside my FirebaseMessagingService) to create an intent. Just prior to being "sent" to the MainActivity page, the intent and extras contain the most recent data received from FCM (everything appears to be working to this point - function below):

const val channelId = "notification_channel"
const val channelName = "com.prod.myApp"

fun generateNotification(goToFragment: String, contact_id: String, source_origin: String){

        val intent = Intent(this, MainActivity::class.java)

        intent.putExtra("fragmentToLoad", goToFragment)
        intent.putExtra("contact_id", contact_id)
        intent.putExtra("source_origin", source_origin)

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

        val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_MUTABLE)

        var builder: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, channelId)
            .setSmallIcon(R.drawable.ic_baseline_back_hand_24)
            .setAutoCancel(true)
            .setVibrate(longArrayOf(1000, 1000, 1000, 1000))
            .setOnlyAlertOnce(true)
            .setContentIntent(pendingIntent)

        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
            notificationManager.createNotificationChannel(notificationChannel)
            }

        notificationManager.notify(0, builder.build())


        }

the intent is received on MainActivity and processed with the following:

onNewIntent(intent) //NOTE: See below

if (intent.extras != null) {

            if(intent.hasExtra("fragmentToLoad")){


                when(intent.getStringExtra("fragmentToLoad").toString()){

                    "GetPic" -> {

                        myViewModel.setContactsOrigin(intent.getStringExtra("source_origin").toString())
                        myViewModel.setPostcardContactID(intent!!.getStringExtra("contact_id").toString())
                        supportFragmentManager.findFragmentById(R.id.myNavHostFragment) as NavHostFragment
                        val navController = navHostFragment.navController
                        navController.navigate(R.id.GetPic)
                    }

                    else -> {
                        Log.d("mainActivity","Intent option " + intent.hasExtra("fragmentToLoad").toString() + " is not an anticipated option")
                    }
                }

            }

this is a separate function in the MainActivity but outside of onCreate:

override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent) // Update the intent with new data
    }

The problem is that the getStringExtra("source_origin") in MainActivity never updates. It is the same value that was submitted the first time the code was run (even though the value has been changed numerous times in the FirebaseMessagingService). For instance, if the first time I ran the app the "source_origin" value in the FirebaseMessagingService was set to "banana", regardless of what I turn that value to on subsequent rerunning of the service, the value in the intent in MainActivity will remain "banana". I could change it to "orange" in the FirebaseMessagingService and by the time it got to MainActivity it would still show as "banana".

The functionality to open the requested fragment works as intended.

This is all happening in the emulator.

I have invalidated caches numerous times including restarting Android Studio. This has no impact on the problem.

Any idea why this error keeps happening?


Solution

  • I was able to move past this issue by amending the requestCode value within the PendingIntent.getActivity(context, requestCode, intent, flags) to always be a unique int value.

    The documentation notes that: "Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does not happen."

    Also, to force the PendingIntent to recognize a difference, we can do the following: "...or different request code integers supplied to #getActivity, #getActivities, getBroadcast, or getService."