Search code examples
androidjsonpostgresqlretrofit2

Android Retrofit2 parsing boolean value always false


I checked the HTTP Response value of my server, the value of restaurant_isfav is t(rue)

{
    "restaurant_average": "9",
    "restaurant_isfav": "t",
    "restaurant_id": "2",
    "restaurant_address": "89 Rue Queen, QC J1M 1J5",
    "restaurant_genre": "Fast Food",
    "restaurant_lat": "45.3654632370656",
    "restaurant_tel": "+18198237007",
    "restaurant_name": "Tim Hortons",
    "restaurant_long": "-71.85717677305372"
},

When it comes to my client, that value turn to false

Restaurant (
    restaurant_id=2, 
    restaurant_name=Tim Hortons,
    restaurant_address=89 Rue Queen, QC J1M 1J5,
    restaurant_genre=Fast Food,
    restaurant_average=9.0,
    restaurant_tel=+18198237007, restaurant_lat=45.365463,
    restaurant_long=-71.85718,
    restaurant_isfav=false
)

I implemented a simple web server with Java and the database is Postgresql

Here's the code related: Gradle

implementation 'com.google.code.gson:gson:2.8.7'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

ViewModel

class HomeViewModel : ViewModel() {
    private val restaurants: MutableLiveData<List<Restaurant>> = MutableLiveData()
    private val request = ServiceBuilder.ServiceBuilder.buildService(EndPointInterface::class.java)
    private lateinit var call: Call<List<Restaurant>>

    fun getRestaurant(): LiveData<List<Restaurant>> {
        return restaurants
    }
    
    fun setRestaurant(id: Int, daoType: Int) {
        call = request.getRestaurants(id, daoType)

        call.enqueue(object : Callback<List<Restaurant>> {
            override fun onResponse(
                call: Call<List<Restaurant>>, response: Response<List<Restaurant>>
            ) {
                if (response.isSuccessful) {
                    restaurants.postValue(response.body())
                }
            }
            override fun onFailure(call: Call<List<Restaurant>>, t: Throwable) {
                t.stackTrace
            }
        })
        
    }
}

Restaurant

data class Restaurant (
    val restaurant_id: Int,
    val restaurant_name: String,
    val restaurant_address: String,
    val restaurant_genre: String,
    val restaurant_average: Float,
    val restaurant_tel: String,
    val restaurant_lat: Float,
    val restaurant_long: Float,
    var restaurant_isfav: Boolean,
)

Solution

  • It's always false because your data "restaurant_isfav": "t", return t not true and return it as string not boolean, your code will works if the data is like "restaurant_isfav": true,

    To solve this problem you can convert restaurant_isfav type from boolean to string and then check if it t or f,

    The other solution is an enum that mapping t to TRUE and f to FALSE

    enum class Favourite {
        @SerializedName("t")
        TRUE,
    
        @SerializedName("f")
        FALSE,
    }
    

    And in Restaurant class you will have

    var restaurant_isfav: Favourite,
    

    And when you check you will write restaurant_isfav.TRUE or restaurant_isfav.FALSE, but if you want to get the boolean value you can write it like this

    enum class Favourite(val boolValue: Boolean) {
    
        @SerializedName("t")
        TRUE(true),
    
        @SerializedName("f")
        FALSE(false),
    }
    

    And you can get the bool value like this restaurant_isfav.TRUE.boolValue

    Don't forget to add com.squareup.retrofit2:converter-scalars to your project