Thursday 26 November 2020

Firebase notification not launching (or launching with delay) app

I'm sending a push notification from Firebase console to my Android App. But sometimes, after receiving the notification and waiting for a couple of hours, and clicking the notification thereafter, it is not opening the app.

PS: In Samsung devices app is opening after a delay of 30+ seconds but in other devices like Mi or Oneplus, it is not opening at all.

Bug video:

In Samsung device

In Mi device

App manifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.baja.app">

<uses-feature
    android:name="android.hardware.camera"
    android:required="false" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
    android:requestLegacyExternalStorage="true"
    android:name=".BajaApplication"
    android:allowBackup="false"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="false"
    android:theme="@style/AppTheme.Default"
    tools:ignore="GoogleAppIndexingWarning">

    <activity
        android:name=".ui.home.HomeActivity"
        android:launchMode="singleTask"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter
            android:label="@string/app_name"
            android:autoVerify="true"
            tools:targetApi="m">
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "example://gizmos” -->
            <data
                android:host="@string/share_host"
                android:scheme="https" />
        </intent-filter>
    </activity>

    <activity
        android:name=".ui.welcome.WelcomeActivity"
        android:screenOrientation="portrait" />

    <activity
        android:name=".ui.home.alarms.ringer.AlarmRingingActivity"
        android:screenOrientation="portrait"
        android:launchMode="singleInstance" />

    <service
        android:name=".media.MediaService"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="android.media.browse.MediaBrowserService" />
        </intent-filter>
    </service>

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

    <service
        android:name=".ui.welcome.AddressIntentService"
        android:exported="false" />

    <service
        android:name=".media.download.InternalMediaDownloadService"
        android:exported="false" />

    <service
        android:name=".media.download.ExternalMediaDownloadService"
        android:exported="false" />

    <service android:name=".ui.home.alarms.ringer.AlarmMediaService" />

    <receiver android:name=".media.download.DownloadCancelReceiver" />

    <receiver
        android:name=".ui.home.alarms.AlarmsBroadcastReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <service
        android:name=".ui.home.alarms.RescheduleAlarmsService"
        android:exported="false" />

    <!--
        MediaSession, prior to API 21, uses a broadcast receiver to communicate with a
        media session. It does not have to be this broadcast receiver, but it must
        handle the action "android.intent.action.MEDIA_BUTTON".
        Additionally, this is used to resume the service from an inactive state upon
        receiving a media button event (such as "play").
    -->
    <receiver android:name="androidx.media.session.MediaButtonReceiver">
        <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
        </intent-filter>
    </receiver> <!-- Disable crash and analytics reporting for debug builds -->

    <meta-data
        android:name="firebase_crashlytics_collection_enabled"
        android:value="${enableCrashReporting}" />
    <meta-data
        android:name="firebase_analytics_collection_deactivated"
        android:value="${disableAnalyticsReporting}" /> <!-- Set custom default icon and color for request notification -->

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel" />
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_favicon" />
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/black" />

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="@string/app_fileprovider_authority"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

onMessageReceived method

override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val notification: RemoteMessage.Notification = remoteMessage.notification ?: return

        val channelId: String = notification.channelId ?: getString(R.string.default_notification_channel)
        val (channelCode: Int, @StringRes channelNameRes: Int, @StringRes channelDescRes: Int) =
            getNotificationChannelRelatedParams(channelId)

        buildAndShowNotification(
            notification.title!!,
            notification.body!!,
            channelId,
            notification.imageUrl,
            remoteMessage.data,
            channelCode,
            channelNameRes,
            channelDescRes
        )
}

Notification builder method

 private fun buildAndShowNotification(
        title: String,
        message: String,
        channelId: String,
        imageUri: Uri?,
        extras: Map<String, String>,
        requestCode: Int,
        @StringRes channelName: Int,
        @StringRes channelDescRes: Int
    ) {
        val defaultSoundUri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)

        val intent: Intent = Intent(this, HomeActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            extras.keys.forEach { key ->
                putExtra(key, extras[key])
            }
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        val builder: NotificationCompat.Builder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_favicon)
            .setColor(Color.BLACK)
            .setContentTitle(title)
            .setContentText(message)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setStyle(NotificationCompat.BigTextStyle().bigText(message))
        applyImageUrl(builder, imageUri)
        val manager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,
                getString(channelName),
                NotificationManager.IMPORTANCE_DEFAULT
            ).apply { description = getString(channelDescRes) }
            manager.createNotificationChannel(channel)
        }

        manager.notify(requestCode, builder.build())
    }

Checking notification intent in HomeActivity, if notification handled by system tray

onCreate(..){
    //statements

    // Check if opened with notification
    val intentData: Triple<String, String?, Boolean> = if (savedInstanceState == null) {
        playFromIntent(intent, appLaunch = true)
    } else {
        Triple("", null, false)
    }

    //statements
}


from Firebase notification not launching (or launching with delay) app

No comments:

Post a Comment