0

I am trying to call firebase cloud messaging api to send push notifications using Retrofit with Kotlin but i keep getting this exception

java.lang.IllegalArgumentException: Unable to create call adapter for retrofit2.Response<okhttp3.ResponseBody> for method NotificationAPI.postNotification W/System.err: at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:755) at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:240) at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:165) at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170) at retrofit2.Retrofit$1.invoke(Retrofit.java:147) at java.lang.reflect.Proxy.invoke(Proxy.java:1006) at $Proxy1.postNotification(Unknown Source) at com.impactech.tracking.firebaseNotification.Notification$sendNotifications$1.invokeSuspend(Notification.kt:29) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571) W/System.err: at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665) Caused by: java.lang.IllegalArgumentException: Could not locate call adapter for retrofit2.Response<okhttp3.ResponseBody>. Tried: * retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory * retrofit2.ExecutorCallAdapterFactory at retrofit2.Retrofit.nextCallAdapter(Retrofit.java:241) at retrofit2.Retrofit.callAdapter(Retrofit.java:205) at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:238)

Api service class

Headers("Authorization:  key=$SERVER_KEY", "Content-Type:$CONTENT_TYPE")
@POST("fcm/send")
suspend fun postNotification(
        @Body notification: PushNotification
):Response<ResponseBody>

RetrofitInstance class

companion object {
    private  val retrofit by lazy {
        Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create()).build()
    }

    val api by lazy {
        retrofit.create(NotificationAPI::class.java)
    }
}

Notification methods:

fun sendMessage(title: String, message: String){
    if(title.isNotEmpty() &&  message.isNotEmpty()){
        PushNotification(
                NotificationData(
                        title, message
                ), TOPIC
        ).also {
            Log.d("TAG", message)
            sendNotifications(it)
        }
    }
}

private fun sendNotifications(notification: PushNotification) = CoroutineScope(Dispatchers.IO).launch {
    try {
        val response = RetrofitInstance.api.postNotification(notification)

        if(response.isSuccessful){
            //Log.d(TAG, "Response: ${Gson().toJson(response)}")
        }else Log.d(TAG, "Response: ${response.errorBody().toString()}")
    }catch (e: Exception){
        e.printStackTrace()
        Log.d(TAG, e.toString())
    }
}

I have been stuck here all night and I can't find a way around it.

Frank van Puffelen
  • 499,950
  • 69
  • 739
  • 734
Joseph Ofem
  • 164
  • 12
  • *firebaser here* Your `postNotification` seems like a security risk. Calls to the FCM REST API require that you specify the FCM *server** key in your code. As its name implies, this key should only be used in server-side code, or in an otherwise trusted environment. The reason for this is that anyone who has the FCM server key can send whatever message they want to all of your users. By including this key in your Android app, a malicious user can find it and you're putting your users at risk. See https://stackoverflow.com/a/37993724 for a better solution. – Frank van Puffelen Sep 13 '21 at 14:12

0 Answers0