Search code examples
androidkotlinretrofitretrofit2moshi

Getting no result from Retrofit call using Moshi


I am new to the API world. While trying to fetch an API using Retrofit and Moshi, it looks like I am getting 0 results, which I should not. Can anyone please tell me what I am doing wrong setting it up?

EDIT: On further investigation, I am actually getting this error in the View Model where I am calling the API:

Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $

The API I'm trying to fetch:

https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2021-01-01&endtime=2021-08-24&minmagnitude=4&latitude=24.0162182&longitude=90.6402874&maxradiuskm=400

Here is my Retrofit and Moshi setup:

private const val BASE_URL = "https://earthquake.usgs.gov/"

private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .baseUrl(BASE_URL)
    .build()

interface UsgsApiService {
    @GET("fdsnws/event/1/query")
    suspend fun getQuakes(
        @Query("format") format: String = "geojson",
        @Query("starttime") starttime: String = "2021-01-01",
        @Query("endtime") endtime: String = "2021-08-24",
        @Query("minmagnitude") minmagnitude: String = "4",
        @Query("latitude") latitude: String = "24.0162182",
        @Query("longitude") longitude: String = "90.6402874",
        @Query("maxradiuskm") maxradiuskm: String = "400"
    ): List<Quake>
}

object UsgsApi {
    val retrofitService: UsgsApiService by lazy {
        retrofit.create(UsgsApiService::class.java)
    }
}

Here is my model:

@JsonClass(generateAdapter = true)
data class Quake(
    @Json(name = "features")
    val features: List<Feature>
)

@JsonClass(generateAdapter = true)
data class Feature(
    @Json(name = "id")
    val id: String,
    @Json(name = "properties")
    val properties: Properties,
    @Json(name = "geometry")
    val geometry: Geometry
)

@JsonClass(generateAdapter = true)
data class Properties(
    @Json(name = "mag")
    val mag: Double?,
    @Json(name = "place")
    val place: String,
    @Json(name = "time")
    val time: Long,
    @Json(name = "url")
    val url: String
)

@JsonClass(generateAdapter = true)
data class Geometry(
    @Json(name = "coordinates")
    val coordinates: List<Double>
)

Thanks for your help!


Solution

  • The API is not returning a json array but you're trying to parse as one with the List<> type.

    What the API returns seems to be a GeoJSON FeatureCollection object with the quake array in its features property, so your top-level json model class should be something that can at least extract the features array.