I am working on an app that interfaces with an API to select from and update a MySQL database.
I am using Kotlin with Retrofit and the Moshi converter. (As I am new to learning all this stuff, this app is modified from the Mars Photo code on https://developer.android.com/courses/pathways/android-basics-kotlin-unit-4-pathway-2 .)
I have successfully implemented the GET part in Retrofit thanks to building out from the above tutorial, but I am having a heck of a time POSTing to the database.
The POST to update via the API works in Postman but I have tried multiple ways to replicate that in my app without success. I have tried a pretty basic POST passing in my data object (as standard Kotlin vars as well as Json annotated or SerializedName annotated), and I have tried Formurlencoded with Fields and Multipart with Parts.
I am including what I hope is all the relevant code (the latest attempt, at least). Thanks for any assistance!
*** My Data Class (have also tried it without the Json annoations) ***
import com.squareup.moshi.Json
data class IsVotes(
@Json(name = "is_votes") var isVotes: String,
@Json(name = "is_id") var isId: String
)
------
*** The function in the ViewModel file - called by a Databinded button click and using static vars for testing
fun updateIsVotes(){
viewModelScope.launch {
// TODO: Response success var?
try {
IsApi.retrofitService.updateVotesAsync( IsVotes("99","5"))
_putStatus.value = IsPutStatus.SUCCESS
}
catch (e:Exception) {
_putStatus.value = IsPutStatus.ALMOST
}
}
}
--------
*** The api service file and call ****
package com.viscidcreates.iswhatapi.network
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import kotlinx.coroutines.Deferred
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.*
private const val BASE_URL = "https://beamcreates.com/is_things_api/v1/"
const val getThings = "Api.php?apicall=getthings"
const val updateVotes = "Api.php?apicall=updatevotes"
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(BASE_URL)
.build()
interface IsApiService {
@GET(getthings)
suspend fun getThings(): List<IsThing>
@POST(updateVotes)
suspend fun updateVotesAsync(@Body votes: IsVotes): Deferred<Response<Void>>
}
object IsApi {
val retrofitService: IsApiService by lazy {
retrofit.create(IsApiService::class.java)
}
}
CodePudding user response:
Normally you create your @Body
classes as :
@JsonClass(generateAdapter = true)
data class IsVotes(
@Json(name = "is_votes")
val isVotes: String,
@Json(name = "is_id")
val isId: String
)
To add the MoshiGenerator you need to add in build.gradle
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"
But first you should try if it's a problem of minify/obfuscation and change
@Json(name="is_votes")
into @field:Json(name="is_votes")
and the same for is_id
.