In the following code snippet, I'm trying to execute a suspend function MessageHandler.handleMessage() in onMessageReceived(), however the function doesn't finish becuase the ioScope is canceled due to onDestroy() being called.
class FcmService : FirebaseMessagingService() {
companion object {
private const val FCM_KEY_MESSAGE = "message"
}
private val conversationsRepo: ConversationsRepoImpl by inject()
private val chatMessagesRepo: ChatMessagesRepoImpl by inject()
private val ioScope = CoroutineScope(Dispatchers.IO)
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
val message = message.data[FCM_KEY_MESSAGE] ?: return
ioScope.launch {
try {
MessageHandler.handleMessage(
conversationsRepo,
chatMessagesRepo,
message
)
} catch (e: Exception) {
Log.e("xxx", "Error: ${e.message.toString()}")
}
}
}
override fun onDestroy() {
super.onDestroy()
Log.d("xxx", "onDestroy()")
ioScope.cancel()
}
}
Here is the log:
onDestroy()
Error: Job was cancelled
How can I make the suspend function finish?
once the message is processed (onMessageReceived finishes) the service is stopped. Since you are starting a new CoroutineScope in there, onMessageReceived is basically returning immediately. Your scope hasn't started yet and when it does onDestroy was called already so the scope was cancelled.
I would suggest deferring the work that needs to be done in the scope to a new WorkManager worker to do what you are trying to do