androidkotlinretrofit

Retrofit data sending


It's my first time trying to fetch data from the server in Kotlin using Retrofit so I'm sorry if the question sounds dumb to you.

API interface

@POST("/api/finger-print")
    suspend fun createFingerPrint(
        @Query("databaseName") name: String,
        @Body type: FingerPrint,
        @Header("Authorization") token:String,
    ): CheckResponse

API function

suspend fun check(dbName:String, token:String, checkType:String): CheckResponse {
        return withContext(Dispatchers.IO) {
            try {
                // Call the Retrofit API method
                val type = FingerPrint(checkType)
                val response = apiService.createFingerPrint(dbName, type, token)
                println(response)
                // Process response here if needed
                response
            } catch (e: HttpException) {
                // Handle HTTP errors
                throw IOException("error 53: $e")
            } catch (e: IOException) {
                // Handle IO errors
                throw IOException("error 56: ${e.message}")
            }
        }
    }

Activity

private suspend fun checkInOut(type: String, callback: (String) -> Unit) {
    try {
      val response = api.check(dbName, token, type)
      println(response)
      val status = response.status

      // Check if the API returned "true" status
      if (status == "true") {
        withContext(Dispatchers.Main) {
          // Success
          callback.invoke("Success")
        }
      } else {
        // Failed
        callback.invoke("CA Error 523")
      }
    } catch (e: Exception) {
      // Catch any unknown errors
      e.printStackTrace()
      callback.invoke("CA Error 532")
    }
  }

Data classes

data class FingerPrint (
    val type:String
)

data class CheckResponse(
  val status:String,
  val data: CheckData
)

data class CheckData(
  val name:String,
  val userID:String,
  val email:String,
  val time:String,
  val date:String,
  val type:String,
  val _id:String,
)

But I keep getting this error: java.io.IOException: error 53: retrofit2.HttpException: HTTP 500 Internal Server Error

The server expects this (This is what I do on Postman)

URL: {{URL}}finger-print?databaseName=myDB Body-raw: {"type":"Check-in"} Authorization: Bearer Token

All data are being sent correctly but I think the problem is with how I'm setting the authorization header

I've checked a couple of online questions like this but I couldn't figure out how to set the token

Also, before that error, I was getting this one

java.io.IOException: error 53: retrofit2.HttpException: HTTP 400 Bad Request

But after I extracted the body part to a data class (was like this @Body type:String) I got the code 500 error


Solution

  • You can apply header using interceptor.

    class HeaderInterceptor() : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            
            
            val builder = Headers.Builder()
            builder.add("Authorization", yourToken)
    
            val request = chain.request().newBuilder()
                .headers(builder.build())
                .build()
            return chain.proceed(request)
        }
    }
    

    Then, build your retrofit client as below.

    object RetrofitBuilder {
        fun build(): ApiService {
            val headerInterceptor = HeaderInterceptor()
            val clientBuilder = OkHttpClient.Builder()
                    .addInterceptor(headerInterceptor)
            val client = clientBuilder.build()
    
            val retrofit = Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(converterFactory)
                .client(client)
                .build()
            return retrofit.create(ApiService::class.java)
        }
    }
    

    Create the service (your API Interface)

    val apiService = RetrofitBuilder.build()
    
    

    Reference https://square.github.io/okhttp/features/interceptors/