Search code examples
androidkotlingetretrofitpojo

Responses from the API are not mapped to the object even when the models are correct


I am using retrofit to make a GET request like this:

@GET("auth/facebook")
    fun facebookSignUp(
        @Query("access_token") access_token: String
    ): Observable<FacebookReturn>

Then I make the request by calling this function:

fun facebookSignUp(access_token: String)
            :MutableLiveData<FacebookReturn>{
        val items = MutableLiveData<FacebookReturn>()
        disposable = apiServe.facebookSignUp(
            access_token
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { result ->
                    items.postValue(result)
                    Log.d("Facebook API", result.toString())
                },
                { error ->
                    Log.d("API ERROR", "API Fetch Error: ${error.message} ")
                }
            )
        return items
    }

The API works well and the returned data looks like this:

{
    "facebook": {
        "statusCode": 200,
        "user": {
            "email": "Disguised",
            "firstName": "Disguised",
            "lastName": "Disguised",
            "token": "Disguised.eyJ1c2VybmFtZSI6bnVsbCwiZW1haWwiOiJwYXVsaXZhbl8zMDAwQHlhaG9vLmNvbSIsImlhdCI6MTYxNDg2NTk1OSwiZXhwIjoxNjE0ODY5NTU5fQ.q0Vn9_4d_-3_WcFfj9s7ZMD3I_0s6XWIEKvXCJuSa_w"
        }
    }
}

I am then trying to convert this data to POJO using the following models and GSON converter library for retrofit:

data class FacebookReturn(
    val facebookUser: FacebookUser
)
data class FacebookUser(
    val statusCode: Int,
    val facebookUserDetails: FacebookUserDetails
)
data class FacebookUserDetails(
    val email: String,
    val firstName: String,
    val lastName: String,
    val token: String
)

However, when I check the logs(Tag: Facebook API) to see the object, it shows that the content is null even though the API actually returned the data. Below I have logs created by HttpInterceptor. I have also looked at similar questions but I don't think it's an encoding or mapping issue, maybe it is, I don't know.

D/OkHttp: --> GET http://Disguised/auth/facebook?access_token=EAANAkZB2CDA4BAIhz74uPKfSZBO2qW52dcK8Qa3AzZASWCQ2Yu055yaUZATy71y92IGOiWpFwBsElRr8st4yhCRgbX2uIVauHMKA3TNyZBTsLcbkKbmMXFmnG9bP1ZBy3CNjJIqTRrqYbt76RhkIh9ZCg1A43kkfrzg6JBLZB9OoJRf5pEYbw8raJDl9nQD5sH5YpmzgD4J2Br4ZB4mHgMdHoFPXdRPdnxDORKcZCPUkkujQZDZD
    --> END GET
I/rventures.tree: Background concurrent copying GC freed 28459(2397KB) AllocSpace objects, 24(1248KB) LOS objects, 49% free, 5115KB/10230KB, paused 1.052ms total 540.715ms
D/OkHttp: <-- 200 OK http://Disguised/auth/facebook?access_token=EAANAkZB2CDA4BAIhz74uPKfSZBO2qW52dcK8Qa3AzZASWCQ2Yu055yaUZATy71y92IGOiWpFwBsElRr8st4yhCRgbX2uIVauHMKA3TNyZBTsLcbkKbmMXFmnG9bP1ZBy3CNjJIqTRrqYbt76RhkIh9ZCg1A43kkfrzg6JBLZB9OoJRf5pEYbw8raJDl9nQD5sH5YpmzgD4J2Br4ZB4mHgMdHoFPXdRPdnxDORKcZCPUkkujQZDZD (651ms)
    X-Powered-By: Express
    Access-Control-Allow-Origin: *
    Content-Type: application/json; charset=utf-8
    Content-Length: 317
    ETag: W/"13d-soe3iGc7MnKumoczrQKKLORbOpw"
    Date: Fri, 05 Mar 2021 05:15:05 GMT
    Connection: keep-alive
D/OkHttp: {"facebook":{"statusCode":200,"user":{"email":"disguised@yahoo.com","firstName":"Disguised","lastName":"Disguised","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6bnVsbCwiZW1haWwiOiJwYXVsaXZhbl8zMDAwQHlhaG9vLmNvbSIsImlhdCI6MTYxNDkyMTMwNSwiZXhwIjoxNjE0OTI0OTA1fQ.6ml4yIu8e7KdrRyIcrAaDDZ8yZqi298utm49FKKccN4"}}}
    <-- END HTTP (317-byte body)
D/Facebook API: FacebookUserDetails(email=null, firstName=null, lastName=null, token=null)
D/Facebook Return: FacebookUserDetails(email=null, firstName=null, lastName=null, token=null)

What could be the issue here?


Solution

  • The name of the fields in your classes must match the JSON fields exactly, or you'll have explitcly tell GSON what name to use with @SerializedName("someName").

    Some of your fields don't match the JSON, which is likely why you're not getting any data into them. The JSON returned gives "facebook": {} as the outer object, so in FacebookReturn you should mark val facebookUser with this serialized name (or rename it to "facebook").

    data class FacebookReturn(
        @SerializedName("facebook")
        val facebookUser: FacebookUser
    )
    

    In FacebookUser as well:

    data class FacebookUser(
        val statusCode: Int,
    
        @SerializedName("user")
        val facebookUserDetails: FacebookUserDetails
    )