feat: Android SDK update for version 25.1.0#129
Conversation
Greptile SummaryThis PR updates the Android SDK to version 25.1.0, adding explicit
Confidence Score: 4/5The PR is safe to merge for most endpoints, but Membership.kt contains an unresolved crash path where a privacy-gated field can be absent from the server response. The header additions across all services are mechanically correct and consistent. The User email metadata fields are deserialized with safe casts and will handle absent server fields gracefully. However, Membership.userAccessedAt is declared non-nullable and deserialized with map["userAccessedAt"] as String — when membership privacy hides this field, the server omits it, map["userAccessedAt"] returns null, and the hard cast throws a ClassCastException at runtime. This was flagged in previous review rounds and has not been addressed. library/src/main/java/io/appwrite/models/Membership.kt — the userAccessedAt field and its deserialization in from() need attention before this can be safely shipped. Important Files Changed
Reviews (5): Last reviewed commit: "chore: update Android SDK to 25.1.0" | Re-trigger Greptile |
| /** | ||
| * Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console. | ||
| */ | ||
| @SerializedName("userAccessedAt") | ||
| val userAccessedAt: String, |
There was a problem hiding this comment.
Declare the field as nullable and use safe casting to avoid a crash when the server omits this key.
| /** | |
| * Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console. | |
| */ | |
| @SerializedName("userAccessedAt") | |
| val userAccessedAt: String, | |
| /** | |
| * Most recent access date in ISO 8601 format. Show this attribute by toggling membership privacy in the Console. | |
| */ | |
| @SerializedName("userAccessedAt") | |
| val userAccessedAt: String?, |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| joined = map["joined"] as String, | ||
| confirm = map["confirm"] as Boolean, | ||
| mfa = map["mfa"] as Boolean, | ||
| userAccessedAt = map["userAccessedAt"] as String, |
| /** | ||
| * Canonical form of the user email address. | ||
| */ | ||
| @SerializedName("emailCanonical") | ||
| var emailCanonical: String?, | ||
|
|
||
| /** | ||
| * Whether the user email is from a free email provider. | ||
| */ | ||
| @SerializedName("emailIsFree") | ||
| var emailIsFree: Boolean?, | ||
|
|
||
| /** | ||
| * Whether the user email is from a disposable email provider. | ||
| */ |
There was a problem hiding this comment.
var used for model fields that should be immutable
The five new email fields (emailCanonical, emailIsFree, emailIsDisposable, emailIsCorporate, emailIsCanonical) are declared as var while every other field in User is val. These are server-returned response values that should not be mutated after construction. The same inconsistency also appears in AppSecret.lastAccessedAt and AppSecretPlaintext.lastAccessedAt in this PR. Using var allows callers to silently overwrite deserialized state, which can lead to stale or incorrect data being observed.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| val idParamName: String? = null | ||
| return client.chunkedUpload( | ||
| apiPath, | ||
| apiHeaders, | ||
| apiParams, | ||
| responseType = io.appwrite.models.Execution::class.java, | ||
| converter, | ||
| paramName, | ||
| idParamName, | ||
| onProgress, | ||
| ) |
There was a problem hiding this comment.
paramName is an unresolved reference — compilation will fail
paramName is never declared in createExecution; it exists only as a local variable in Storage.createFile (val paramName = "file"). Kotlin will reject this with an "unresolved reference" error, so the entire SDK will not build. Beyond the missing declaration, chunkedUpload immediately does params[paramName] as InputFile, but createExecution has no InputFile parameter — its payload is a body: String?. The function should continue using client.call("POST", …) as it did before this PR, with "content-type" to "application/json" restored.
This PR contains updates to the Android SDK for version 25.1.0.