git.iko.soy/parseable-android
on master help sign in
Fix login failure: AboutInfo.license type mismatch with server response (#8)

The Parseable server returns `license` as a JSON object (with fields like `name`, `version`, `plan`) but the Android model declared it as `String?`. This caused a SerializationException during login, surfacing as "Invalid response format from server". Changed the field to `JsonObject?` to match the actual API response, and updated the settings screen to extract the license name for display. https://claude.ai/code/session_018HZWpUGDJM2S2EQ3Ee8DMh Co-authored-by: Claude <noreply@anthropic.com>

commit4be24bc72114b6246c4a4385f5249b11733bb9b6 authoriko <mail@iko.soy> dateSun 15 Feb 2026, 16:45 (8 months ago) parent6f1a3c3
3 files changed+7−3
app/src/main/java/com/parseable/android/data/model/Models.kt+1−1 app/src/main/java/com/parseable/android/ui/screens/settings/SettingsScreen.kt+3−1 app/src/test/java/com/parseable/android/SettingsViewModelTest.kt+3−1
app/src/main/java/com/parseable/android/data/model/Models.kt+1−1
@@ -107,7 +107,7 @@ data class AboutInfo(
107107 val commit: String? = null,
108108 @SerialName("deploymentId")
109109 val deploymentId: String? = null,
110− val license: String? = null,
110+ val license: JsonObject? = null,
111111 val mode: String? = null,
112112 val staging: String? = null,
113113 val store: JsonObject? = null,
app/src/main/java/com/parseable/android/ui/screens/settings/SettingsScreen.kt+3−1
@@ -16,6 +16,8 @@ import androidx.compose.ui.unit.dp
1616import androidx.hilt.navigation.compose.hiltViewModel
1717import androidx.lifecycle.compose.collectAsStateWithLifecycle
1818import com.parseable.android.BuildConfig
19+import kotlinx.serialization.json.contentOrNull
20+import kotlinx.serialization.json.jsonPrimitive
1921
2022@OptIn(ExperimentalMaterial3Api::class)
2123@Composable
@@ -153,7 +155,7 @@ fun SettingsScreen(
153155 about.version?.let { SettingsRow("Version", it) }
154156 about.commit?.let { SettingsRow("Commit", it.take(12)) }
155157 about.mode?.let { SettingsRow("Mode", it) }
156− about.license?.let { SettingsRow("License", it) }
158+ about.license?.get("name")?.jsonPrimitive?.contentOrNull?.let { SettingsRow("License", it) }
157159 about.deploymentId?.let { SettingsRow("Deployment ID", it.take(12)) }
158160 about.queryEngine?.let { SettingsRow("Query Engine", it) }
159161 }
app/src/test/java/com/parseable/android/SettingsViewModelTest.kt+3−1
@@ -3,6 +3,8 @@ package com.parseable.android
33import com.parseable.android.data.model.AboutInfo
44import com.parseable.android.data.model.ApiResult
55import com.parseable.android.data.model.ServerConfig
6+import kotlinx.serialization.json.buildJsonObject
7+import kotlinx.serialization.json.put
68import com.parseable.android.data.repository.ParseableRepository
79import com.parseable.android.data.repository.SettingsRepository
810import com.parseable.android.ui.screens.settings.SettingsViewModel
@@ -60,7 +62,7 @@ class SettingsViewModelTest {
6062
6163 @Test
6264 fun `load sets about info on success`() = runTest {
63− val about = AboutInfo(version = "1.2.0", mode = "standalone", license = "AGPL")
65+ val about = AboutInfo(version = "1.2.0", mode = "standalone", license = buildJsonObject { put("name", "AGPL") })
6466 coEvery { settingsRepository.serverConfig } returns flowOf(null)
6567 coEvery { repository.getAbout() } returns ApiResult.Success(about)
6668 coEvery { repository.listUsers() } returns ApiResult.Success(emptyList())