I am working on small project on a Jetpack Compose. I am trying to data from a static JSON File from this url using Retrofit. https://firebasestorage.googleapis.com/v0/b/culoader.appspot.com/o/json%2Fcudata.json?alt=media&token=d0679703-2f6c-440f-af03-d4d61305cc84
Network Module
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun proveidesCurrencyService() : CurrencyService{
return Retrofit.Builder()
.baseUrl("https://firebasestorage.googleapis.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(CurrencyService::class.java)
}
}
Service Class
interface CurrencyService {
//@Streaming
@GET
suspend fun getCurrencyFile(@Url fileUrl:String): Response<ResponseBody>
}
data class CurrencyAPIResponse(
@SerializedName("data") var data: MutableState<List<CurrencyRates>>
)
data class CurrencyRates (
@SerializedName("code") var code : String,
@SerializedName("value") var value : String
)
ViewModel
@HiltViewModel
class CurrencyDataViewModel
@Inject
constructor(private val currencyService: CurrencyService
) : ViewModel()
{
init {
getCurrencyFileData()
}
}
fun getCurrencyFileData() = viewModelScope.launch(Dispatchers.IO) {
val url: String =
"https://firebasestorage.googleapis.com/v0/b/culoader.appspot.com/o/json%2Fcudata.json?alt=media&token=d0679703-2f6c-440f-af03-d4d61305cc84"
val responseBody = currencyService.getCurrencyFile(url).body()
if (responseBody != null) {
Log.d("\nresponsebody", responseBody.string())
val gson = GsonBuilder().setPrettyPrinting().create()
val currencyAPIResponse = gson.fromJson(responseBody.string(), CurrencyAPIResponse::class.java)
val data: MutableState<List<CurrencyRates>> = currencyAPIResponse.data
Log.d("Data", data.value[0].code)
}
}
Everytime, I am getting the below error,
Attempt to invoke virtual method 'androidx.compose.runtime.MutableState com.tuts.playlite.network.response.CurrencyAPIResponse.getData()' on a null object reference
Not sure, where I am failing, I have tried to convert this to JSON Object, but still failing. Is it right way to get the data?
Another thing noticed that even though the JSON file is complete in the url, the response body log is showing the JSON with some other content.
{
"code": "IMP",
"value": "0.722603"
},
{
"code": "INR",
[ 1631385414.170 12452:12478 D/
responsebody]
"value": "72.99465"
},
{
"code": "IQD",
"value": "1458.61356"
},
As a result, the GSON might not able to form the json and hence could be getting null exception. Not sure why random text is getting added!
Finally, the culprit seems to be responseBody Stream. After I changed the code with below, It seems to be working. I assume, it was unable to get the proper complete JSON earlier and throwing the null object reference error.
val responseBody = currencyService.getCurrencyFile(url).body()
val resData = responseBody?.byteStream()!!.bufferedReader().use {
it.readText()
}
val gson = GsonBuilder().setPrettyPrinting().create()
val currencyAPIResponse = gson.fromJson(resData, CurrencyAPIResponse::class.java)
Thank you for all support!