I am using FirebaseMessagingService
to show push notifications in my app. Now I need to show notification history, to do this I decided to save notifications to Room database and show them, when it will be needed. Here I faced a problem, saving notifications works fine when app is in focus, and doesn't work at all when app is in background or stopped. Push notifications are always shown normally, so no accusations to Firebase here.
I tried to different approaches to save notifications data to Room. In first I saved them directly in FirebaseMessagingService
:
class FirebaseCloudMessagingService : FirebaseMessagingService(), KoinComponent {
private val notificationUc by inject<NotificationUc>()
override fun onMessageReceived(message: RemoteMessage) {
val data = message.data
Log.i("FCM Service", "Received message:\n• notification title: ${message.notification?.title}" +
"\n• notification body: ${message.notification?.body}\n• data: $data")
CoroutineScope(Dispatchers.IO).launch { handleMessage(data) }
}
private suspend fun handleMessage(bundle: Map<String, String>) {
val balance: String? = bundle[BALANCE_KEY]
val amount: String? = bundle[AMOUNT_KEY]
val message: String? = bundle[MESSAGE_KEY]
val pushId: Int? = bundle[PUSH_ID_KEY]?.toInt()
EventBus.getInstance().post(ActionEvent.Push(balance, amount, message, pushId)
if (!message.isNullOrEmpty()) {
showNotification(message)
}
notificationUc.savePush(balance, amount, message, pushId)
}
}
This solution works when app is focused, but when app is in background for some time push is still shown, but data are not saved to database. I tried another way to save data using EventBus (it worked in example I found).
I moved saving to database to MainActivity
and pass data there with EventBus:
class MainActivity : AppCompatActivity() {
private val mainViewModel by viewModels<MainActivityViewModel>()
//Rest of the code
@Subscribe
fun eventPush(newEvent: ActionEvent) {
val event: ActionEvent.Push = newEvent as? ActionEvent.Push ?: return
//Rest of the code
mainViewModel.savePush(event)
}
}
class MainActivityViewModel : ViewModel(), CoroutineScope, KoinComponent {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
private val notificationUc by inject<NotificationUc>()
//Rest of code
fun savePush(push: ActionEvent.Push) {
launch(coroutineContext) {
withContext(Dispatchers.IO) {
with(push) {
notificationUc.savePush(balance, amount, message, pushId, pointId)
}
}
}
}
}
Unfortunately this solution works the same way as previous. I hope to find way to save notification data to database no matter app is focused or in background.