Notification from Firebase does not show when app is closed

I made 2 Sheets and 1 Popup in different files to make the code of the MainActivity tidy and to call on them in a wrapped file called HSApp.kt. This, when the User taps the notification, each respective sheet or popup will show.

The notifications show now, but only when the app is opened.
Can anyone kindly help me, please? :folded_hands:t2:

MYFIREBASEMESSAGINGSERVICE.kt:


class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        // Check if the message contains notification payload
        remoteMessage.notification?.let {
            showNotification(it.title, it.body, remoteMessage.data["type"])
        }

        // Check if the message contains data payload
        if (remoteMessage.data.isNotEmpty()) {
            val title = remoteMessage.data["title"]
            val message = remoteMessage.data["message"]
            val type = remoteMessage.data["type"] // "devotional", "quiz", "word_for_the_day"

            // Show a notification only if there's no UI popover to be displayed
            if (type.isNullOrEmpty()) {
                showNotification(title, message, null)
            } else {
                handleFirebaseEvent(type)
            }
        }
    }

    private fun handleFirebaseEvent(type: String) {
        // Send a broadcast with the action defined in our constant.
        val intent = Intent(NOTIFICATION_TRIGGER_ACTION).apply {
            putExtra("type", type)
        }
        sendBroadcast(intent)
    }

    private fun showNotification(title: String?, message: String?, type: String?) {
        val channelId = "default_channel_id"
        val channelName = "Default Channel"
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Create notification channel (API 26+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT
            ).apply {
                description = "Default channel for app notifications"
            }
            notificationManager.createNotificationChannel(channel)
        }

        // Intent to open MainActivity when tapped
        val intent = Intent(this, MainActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            putExtra("notification_type", type)
        }

        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
        )

        // Build the notification
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setContentTitle(title)
            .setContentText(message)
            .setSmallIcon(R.drawable.logo_image)
            .setColor(Color.parseColor("#660d77"))
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)

        // Show the notification
        notificationManager.notify(0, notificationBuilder.build())
    }

    override fun onNewToken(token: String) {
        Log.d("MyAppFCM", "New token: $token")
        sendTokenToServer(token)
    }

    private fun sendTokenToServer(token: String) {
        Log.d("FCM", "Firebase token: $token")
        // TODO: Implement API call to send the token to your backend
    }

    }

MAINACTIVITY:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Initialize Firebase
        FirebaseApp.initializeApp(this)

        if (!checkPermissions()) {
            requestPermissions()
        }
        val notificationType: String? = intent.getStringExtra("notification_type")
        setContent {
            // Pass the notification extra to HSMApp.
            HSMApp(notificationType = notificationType)
        }

    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
    }


HSMAPP.kt:

@Composable
fun HSMApp(notificationType: String?) {
    var isDevotionalSheetVisible by remember { mutableStateOf(false) }
    var isQuizSheetVisible by remember { mutableStateOf(false) }
    var isWordPopupVisible by remember { mutableStateOf(false) }

    val context = LocalContext.current

    // Use LaunchedEffect keyed on the passed notificationType to update state.
    LaunchedEffect(notificationType) {
        notificationType?.let { type ->
            when (type) {
                "devotional" -> isDevotionalSheetVisible = true
                "quiz" -> isQuizSheetVisible = true
                "wordPopup", "word_for_the_day" -> isWordPopupVisible = true
            }
        }
    }

    // Also register a BroadcastReceiver for in-app triggers.
    DisposableEffect(Unit) {
        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                val type = intent?.getStringExtra("type")
                when (type) {
                    "devotional" -> isDevotionalSheetVisible = true
                    "quiz" -> isQuizSheetVisible = true
                    "wordPopup", "word_for_the_day" -> isWordPopupVisible = true
                }
            }
        }
        val filter = IntentFilter(NOTIFICATION_TRIGGER_ACTION)
        context.registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED)
        onDispose { context.unregisterReceiver(receiver) }
    }

    HSMAppTheme {
        // Pass dummy lambdas to MainScreen (if youโ€™re not using buttons in production).
        MainScreen(
            onDismiss = {
                isDevotionalSheetVisible = false
                isQuizSheetVisible = false
                isWordPopupVisible = false
            },
            showDevotionalSheet = { isDevotionalSheetVisible = true },
            showQuizSheet = { isQuizSheetVisible = true },
            showWordPopup = { isWordPopupVisible = true }
        )

        if (isDevotionalSheetVisible) {
            DevotionalSheet(onDismiss = { isDevotionalSheetVisible = false })
        }
        if (isQuizSheetVisible) {
            QuizSheet(onDismiss = { isQuizSheetVisible = false })
        }
        if (isWordPopupVisible) {
            WordForTheDayPopup(onDismiss = { isWordPopupVisible = false })
        }
    }
}


DEVOTIONAL Example of Sheet:

@Composable
fun DevotionalSheet(onDismiss: () -> Unit) {
    ModalBottomSheet(
        onDismissRequest = { onDismiss() },
        sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
        containerColor = Color.White,
        shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp)
    ) {
        WebViewPage(url = "https://www.google.comโ€)
    }
}