admin管理员组

文章数量:1023744

A custom push notification is send from backend. The payload is bellow

Payload

{
    "data": {
        "notification": {
            "title": "কথা চলুক সেরা অফারে!",
            "body": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "imageUrl": ".png"
        },
        "data": {
            "title": "কথা চলুক সেরা অফারে!",
            "description": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "sentAt": "1731929876", //
            "expiredAt": "1731982676",
            "buttonText": "Open Recharge",
            "type": "in_app",
            "url": "myapp-ppd://dashboard",
            "image": ".gif"
        },
        "token": "XXX"
    },
    "operator": "moon"
}

What I have to do is, is to save the Notification data to my Room Data base. Here is the implementation, I tried

SaveNotificationWorker.kt

@HiltWorker
class SaveNotificationWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override suspend fun doWork(): Result {
        val jsonString = inputData.getString("data")

        if (jsonString.isNullOrEmpty()) return Result.failure()

        return try {
            val notificationEntity = Gson().fromJson(jsonString, NotificationEntity::class.java)

            notificationRepository.addNotification(notificationEntity)
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }

}

RasaFcmService.kt

@AndroidEntryPoint
class RasaFcmService : FirebaseMessagingService() {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d("fcm", token)
    }

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

        val notificationEntity = parseData(remoteMessage.data)

        notificationEntity?.let {
            val jsonString = Gson().toJson(notificationEntity)
            val workRequest = OneTimeWorkRequestBuilder<SaveNotificationWorker>()
                .setInputData(workDataOf("data" to jsonString))
                .build()

            WorkManager.getInstance(applicationContext).enqueue(workRequest)

            showNotification(it.id, it.title, it.description)
        }
    }

    private fun parseData(data: Map<String, String>): NotificationEntity? {
        return try {
            val notificationJson = JSONObject(data)

            val title = notificationJson.optString("title")
            val description = notificationJson.optString("description")
            val sentAt = notificationJson.optLong("sentAt", System.currentTimeMillis() / 1000)

            val linkType = if (notificationJson.has("type")) notificationJson.optString("type") else null
            val link = if (notificationJson.has("url")) notificationJson.optString("url") else null

            val image = if (notificationJson.has("image")) notificationJson.optString("image") else null

            val expiredAt =  if (notificationJson.has("expiredAt")) notificationJson.optString("expiredAt") else null
            val buttonText =  notificationJson.optString("buttonText")

            NotificationEntity(
                title = title,
                description = description,
                date = sentAt,
                isRead = 0,
                expiredAt = expiredAt?.toLong(),
                buttonText = buttonText,
                linkType = linkType,
                link = link,
                image = image
            )

        } catch (e: Exception) {
            null
        }
    }

    private fun showNotification(id: Int, title: String, description: String) {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channelId = "YOUR_CHANNEL_ID"
        val channelName = "Your Channel Name"

        val intent = Intent(this, SplashActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            putExtra("notification_id", id)
        }
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

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

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle(title)
            .setContentText(description)
            .setSmallIcon(R.drawable.ic_brand_logo)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build()

        notificationManager.notify(id, notification)
    }

}

In this implementation, when app is in foreground, data is saved perfectly in Room. But when app is in background or not in active mood, data is not saved although I want to save it in Room even if app is in background. How to solve this issue?

A custom push notification is send from backend. The payload is bellow

Payload

{
    "data": {
        "notification": {
            "title": "কথা চলুক সেরা অফারে!",
            "body": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "imageUrl": "https://myapp-dev-static.robi.bd/images/payment/bkash.png"
        },
        "data": {
            "title": "কথা চলুক সেরা অফারে!",
            "description": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "sentAt": "1731929876", //
            "expiredAt": "1731982676",
            "buttonText": "Open Recharge",
            "type": "in_app",
            "url": "myapp-ppd://dashboard",
            "image": "https://media.giphy/media/Ju7l5y9osyymQ/giphy.gif"
        },
        "token": "XXX"
    },
    "operator": "moon"
}

What I have to do is, is to save the Notification data to my Room Data base. Here is the implementation, I tried

SaveNotificationWorker.kt

@HiltWorker
class SaveNotificationWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override suspend fun doWork(): Result {
        val jsonString = inputData.getString("data")

        if (jsonString.isNullOrEmpty()) return Result.failure()

        return try {
            val notificationEntity = Gson().fromJson(jsonString, NotificationEntity::class.java)

            notificationRepository.addNotification(notificationEntity)
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }

}

RasaFcmService.kt

@AndroidEntryPoint
class RasaFcmService : FirebaseMessagingService() {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d("fcm", token)
    }

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

        val notificationEntity = parseData(remoteMessage.data)

        notificationEntity?.let {
            val jsonString = Gson().toJson(notificationEntity)
            val workRequest = OneTimeWorkRequestBuilder<SaveNotificationWorker>()
                .setInputData(workDataOf("data" to jsonString))
                .build()

            WorkManager.getInstance(applicationContext).enqueue(workRequest)

            showNotification(it.id, it.title, it.description)
        }
    }

    private fun parseData(data: Map<String, String>): NotificationEntity? {
        return try {
            val notificationJson = JSONObject(data)

            val title = notificationJson.optString("title")
            val description = notificationJson.optString("description")
            val sentAt = notificationJson.optLong("sentAt", System.currentTimeMillis() / 1000)

            val linkType = if (notificationJson.has("type")) notificationJson.optString("type") else null
            val link = if (notificationJson.has("url")) notificationJson.optString("url") else null

            val image = if (notificationJson.has("image")) notificationJson.optString("image") else null

            val expiredAt =  if (notificationJson.has("expiredAt")) notificationJson.optString("expiredAt") else null
            val buttonText =  notificationJson.optString("buttonText")

            NotificationEntity(
                title = title,
                description = description,
                date = sentAt,
                isRead = 0,
                expiredAt = expiredAt?.toLong(),
                buttonText = buttonText,
                linkType = linkType,
                link = link,
                image = image
            )

        } catch (e: Exception) {
            null
        }
    }

    private fun showNotification(id: Int, title: String, description: String) {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channelId = "YOUR_CHANNEL_ID"
        val channelName = "Your Channel Name"

        val intent = Intent(this, SplashActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            putExtra("notification_id", id)
        }
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

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

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle(title)
            .setContentText(description)
            .setSmallIcon(R.drawable.ic_brand_logo)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build()

        notificationManager.notify(id, notification)
    }

}

In this implementation, when app is in foreground, data is saved perfectly in Room. But when app is in background or not in active mood, data is not saved although I want to save it in Room even if app is in background. How to solve this issue?

Share Improve this question asked Nov 19, 2024 at 6:33 Aminul Haque AomeAminul Haque Aome 2,62926 silver badges40 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 2

Why Push Notification Data Isn’t Saved to Room When the App is in Background

When working with Firebase Cloud Messaging (FCM), the behavior of notifications depends on how the payload is structured. FCM allows two types of payloads: notification payloads and data payloads. Understanding their behavior is crucial to ensure that your app handles notifications and saves data correctly.

  1. Notification Payload

When the payload contains a notification object, FCM automatically handles the notification display. This means:

•   The notification is shown in the system tray by FCM without involving your app.
•   The FirebaseMessagingService’s onMessageReceived() method is not triggered if the app is in the background or terminated.
•   You cannot directly process the notification payload to save it to the Room database in these cases.
  1. Data Payload

When the payload contains only a data object:

•   The onMessageReceived() method is triggered in all app states (foreground, background, or terminated).
•   You have full control to process the data and handle tasks like saving it to Room, displaying a custom notification, etc.
enter code here
  1. Mixed Payload (Both notification and data)

If the payload includes both notification and data objects:

•   FCM prioritizes the notification object for background and terminated states, displaying it automatically in the system tray.
•   The data object is ignored, and onMessageReceived() is not called.

Solution

To handle and save push notification data to Room effectively:

•   Use only the data payload in your backend’s FCM request. Avoid including the notification object.
•   Construct your custom notification in the onMessageReceived() method, allowing you to display the notification and save its content to Room simultaneously.

Example Payloads

Notification Payload (Not Recommended):

{
  "notification": {
    "title": "New Offer!",
    "body": "Click to check out the latest deals."
  },
  "data": {
    "type": "offer",
    "url": "https://example/deals"
  }
}

• Background Behavior: Auto-shows notification, onMessageReceived() not triggered.

Data Payload (Recommended):

{
  "data": {
    "title": "New Offer!",
    "body": "Click to check out the latest deals.",
    "type": "offer",
    "url": "https://example/deals"
  }
}

• Background Behavior: onMessageReceived() is triggered, giving you full control.

Backend Implementation

Ensure your backend sends only the data object to allow consistent handling of notifications across all app states. This provides flexibility to customize notifications and handle tasks like saving data to Room.

For background tasks use the old way and don't use HILT. Try this in onMessageReceived

//initialize database 
//after using the below approach
CoroutineScope(Dispatchers.IO).launch {
          //save to database code
 }

A custom push notification is send from backend. The payload is bellow

Payload

{
    "data": {
        "notification": {
            "title": "কথা চলুক সেরা অফারে!",
            "body": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "imageUrl": ".png"
        },
        "data": {
            "title": "কথা চলুক সেরা অফারে!",
            "description": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "sentAt": "1731929876", //
            "expiredAt": "1731982676",
            "buttonText": "Open Recharge",
            "type": "in_app",
            "url": "myapp-ppd://dashboard",
            "image": ".gif"
        },
        "token": "XXX"
    },
    "operator": "moon"
}

What I have to do is, is to save the Notification data to my Room Data base. Here is the implementation, I tried

SaveNotificationWorker.kt

@HiltWorker
class SaveNotificationWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override suspend fun doWork(): Result {
        val jsonString = inputData.getString("data")

        if (jsonString.isNullOrEmpty()) return Result.failure()

        return try {
            val notificationEntity = Gson().fromJson(jsonString, NotificationEntity::class.java)

            notificationRepository.addNotification(notificationEntity)
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }

}

RasaFcmService.kt

@AndroidEntryPoint
class RasaFcmService : FirebaseMessagingService() {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d("fcm", token)
    }

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

        val notificationEntity = parseData(remoteMessage.data)

        notificationEntity?.let {
            val jsonString = Gson().toJson(notificationEntity)
            val workRequest = OneTimeWorkRequestBuilder<SaveNotificationWorker>()
                .setInputData(workDataOf("data" to jsonString))
                .build()

            WorkManager.getInstance(applicationContext).enqueue(workRequest)

            showNotification(it.id, it.title, it.description)
        }
    }

    private fun parseData(data: Map<String, String>): NotificationEntity? {
        return try {
            val notificationJson = JSONObject(data)

            val title = notificationJson.optString("title")
            val description = notificationJson.optString("description")
            val sentAt = notificationJson.optLong("sentAt", System.currentTimeMillis() / 1000)

            val linkType = if (notificationJson.has("type")) notificationJson.optString("type") else null
            val link = if (notificationJson.has("url")) notificationJson.optString("url") else null

            val image = if (notificationJson.has("image")) notificationJson.optString("image") else null

            val expiredAt =  if (notificationJson.has("expiredAt")) notificationJson.optString("expiredAt") else null
            val buttonText =  notificationJson.optString("buttonText")

            NotificationEntity(
                title = title,
                description = description,
                date = sentAt,
                isRead = 0,
                expiredAt = expiredAt?.toLong(),
                buttonText = buttonText,
                linkType = linkType,
                link = link,
                image = image
            )

        } catch (e: Exception) {
            null
        }
    }

    private fun showNotification(id: Int, title: String, description: String) {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channelId = "YOUR_CHANNEL_ID"
        val channelName = "Your Channel Name"

        val intent = Intent(this, SplashActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            putExtra("notification_id", id)
        }
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

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

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle(title)
            .setContentText(description)
            .setSmallIcon(R.drawable.ic_brand_logo)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build()

        notificationManager.notify(id, notification)
    }

}

In this implementation, when app is in foreground, data is saved perfectly in Room. But when app is in background or not in active mood, data is not saved although I want to save it in Room even if app is in background. How to solve this issue?

A custom push notification is send from backend. The payload is bellow

Payload

{
    "data": {
        "notification": {
            "title": "কথা চলুক সেরা অফারে!",
            "body": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "imageUrl": "https://myapp-dev-static.robi.bd/images/payment/bkash.png"
        },
        "data": {
            "title": "কথা চলুক সেরা অফারে!",
            "description": "১৯৯ টাকায় ৩০০ মিনিট ৩০ দিন মেয়াদে পেতে ট্যাপ করুন!",
            "sentAt": "1731929876", //
            "expiredAt": "1731982676",
            "buttonText": "Open Recharge",
            "type": "in_app",
            "url": "myapp-ppd://dashboard",
            "image": "https://media.giphy/media/Ju7l5y9osyymQ/giphy.gif"
        },
        "token": "XXX"
    },
    "operator": "moon"
}

What I have to do is, is to save the Notification data to my Room Data base. Here is the implementation, I tried

SaveNotificationWorker.kt

@HiltWorker
class SaveNotificationWorker @AssistedInject constructor(
    @Assisted context: Context,
    @Assisted workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override suspend fun doWork(): Result {
        val jsonString = inputData.getString("data")

        if (jsonString.isNullOrEmpty()) return Result.failure()

        return try {
            val notificationEntity = Gson().fromJson(jsonString, NotificationEntity::class.java)

            notificationRepository.addNotification(notificationEntity)
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }

}

RasaFcmService.kt

@AndroidEntryPoint
class RasaFcmService : FirebaseMessagingService() {

    @Inject
    lateinit var notificationRepository: NotificationLocalRepository

    override fun onNewToken(token: String) {
        super.onNewToken(token)
        Log.d("fcm", token)
    }

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

        val notificationEntity = parseData(remoteMessage.data)

        notificationEntity?.let {
            val jsonString = Gson().toJson(notificationEntity)
            val workRequest = OneTimeWorkRequestBuilder<SaveNotificationWorker>()
                .setInputData(workDataOf("data" to jsonString))
                .build()

            WorkManager.getInstance(applicationContext).enqueue(workRequest)

            showNotification(it.id, it.title, it.description)
        }
    }

    private fun parseData(data: Map<String, String>): NotificationEntity? {
        return try {
            val notificationJson = JSONObject(data)

            val title = notificationJson.optString("title")
            val description = notificationJson.optString("description")
            val sentAt = notificationJson.optLong("sentAt", System.currentTimeMillis() / 1000)

            val linkType = if (notificationJson.has("type")) notificationJson.optString("type") else null
            val link = if (notificationJson.has("url")) notificationJson.optString("url") else null

            val image = if (notificationJson.has("image")) notificationJson.optString("image") else null

            val expiredAt =  if (notificationJson.has("expiredAt")) notificationJson.optString("expiredAt") else null
            val buttonText =  notificationJson.optString("buttonText")

            NotificationEntity(
                title = title,
                description = description,
                date = sentAt,
                isRead = 0,
                expiredAt = expiredAt?.toLong(),
                buttonText = buttonText,
                linkType = linkType,
                link = link,
                image = image
            )

        } catch (e: Exception) {
            null
        }
    }

    private fun showNotification(id: Int, title: String, description: String) {
        val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channelId = "YOUR_CHANNEL_ID"
        val channelName = "Your Channel Name"

        val intent = Intent(this, SplashActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            putExtra("notification_id", id)
        }
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

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

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle(title)
            .setContentText(description)
            .setSmallIcon(R.drawable.ic_brand_logo)
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            .setAutoCancel(true)
            .setContentIntent(pendingIntent)
            .build()

        notificationManager.notify(id, notification)
    }

}

In this implementation, when app is in foreground, data is saved perfectly in Room. But when app is in background or not in active mood, data is not saved although I want to save it in Room even if app is in background. How to solve this issue?

Share Improve this question asked Nov 19, 2024 at 6:33 Aminul Haque AomeAminul Haque Aome 2,62926 silver badges40 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 2

Why Push Notification Data Isn’t Saved to Room When the App is in Background

When working with Firebase Cloud Messaging (FCM), the behavior of notifications depends on how the payload is structured. FCM allows two types of payloads: notification payloads and data payloads. Understanding their behavior is crucial to ensure that your app handles notifications and saves data correctly.

  1. Notification Payload

When the payload contains a notification object, FCM automatically handles the notification display. This means:

•   The notification is shown in the system tray by FCM without involving your app.
•   The FirebaseMessagingService’s onMessageReceived() method is not triggered if the app is in the background or terminated.
•   You cannot directly process the notification payload to save it to the Room database in these cases.
  1. Data Payload

When the payload contains only a data object:

•   The onMessageReceived() method is triggered in all app states (foreground, background, or terminated).
•   You have full control to process the data and handle tasks like saving it to Room, displaying a custom notification, etc.
enter code here
  1. Mixed Payload (Both notification and data)

If the payload includes both notification and data objects:

•   FCM prioritizes the notification object for background and terminated states, displaying it automatically in the system tray.
•   The data object is ignored, and onMessageReceived() is not called.

Solution

To handle and save push notification data to Room effectively:

•   Use only the data payload in your backend’s FCM request. Avoid including the notification object.
•   Construct your custom notification in the onMessageReceived() method, allowing you to display the notification and save its content to Room simultaneously.

Example Payloads

Notification Payload (Not Recommended):

{
  "notification": {
    "title": "New Offer!",
    "body": "Click to check out the latest deals."
  },
  "data": {
    "type": "offer",
    "url": "https://example/deals"
  }
}

• Background Behavior: Auto-shows notification, onMessageReceived() not triggered.

Data Payload (Recommended):

{
  "data": {
    "title": "New Offer!",
    "body": "Click to check out the latest deals.",
    "type": "offer",
    "url": "https://example/deals"
  }
}

• Background Behavior: onMessageReceived() is triggered, giving you full control.

Backend Implementation

Ensure your backend sends only the data object to allow consistent handling of notifications across all app states. This provides flexibility to customize notifications and handle tasks like saving data to Room.

For background tasks use the old way and don't use HILT. Try this in onMessageReceived

//initialize database 
//after using the below approach
CoroutineScope(Dispatchers.IO).launch {
          //save to database code
 }

本文标签: In AndroidCan39t save push notification data to Room when app is in backgroundStack Overflow