Update UserInfo.kt#13
Conversation
The preferred_username, updated_at, given_name and family_name fields captured as null on the userinfo object. This is due to a failure on gson.fromJson conversion for fields with underscores. Proposing adding annotation for resolving this issue. Best Regards James
There was a problem hiding this comment.
Pull request overview
This PR fixes a deserialization issue where fields with underscores (preferred_username, updated_at, given_name, family_name) in the JSON response were not being mapped correctly to the camelCase Kotlin properties, resulting in null values. The fix adds Gson @SerializedName annotations to map the JSON field names to the Kotlin properties, and introduces a JSONConvertable interface with helper methods for JSON serialization/deserialization.
Key changes:
- Added
@SerializedNameannotations to map JSON snake_case fields to Kotlin camelCase properties - Introduced
JSONConvertableinterface with JSON conversion helper methods - Added Gson import statements
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -1,12 +1,21 @@ | |||
| package com.onelogin.oidc.userInfo | |||
|
|
|||
| import com.google.gson.Gson | |||
There was a problem hiding this comment.
The Gson import is used only in the newly added JSONConvertable interface, not in the UserInfo data class itself. Consider moving the JSONConvertable interface and its extension function to a separate utility file to keep concerns separated and avoid coupling the UserInfo data class with Gson implementation details.
| interface JSONConvertable { | ||
| fun toJSON(): String = Gson().toJson(this) | ||
| } | ||
|
|
||
| inline fun <reified T: JSONConvertable> String.toObject(): T = Gson().fromJson(this, T::class.java) |
There was a problem hiding this comment.
Creating new Gson instances on every serialization/deserialization call is inefficient. Gson objects are thread-safe and intended to be reused. Consider creating a single shared Gson instance to avoid the overhead of repeated instantiation.
| interface JSONConvertable { | |
| fun toJSON(): String = Gson().toJson(this) | |
| } | |
| inline fun <reified T: JSONConvertable> String.toObject(): T = Gson().fromJson(this, T::class.java) | |
| private val gson = Gson() | |
| interface JSONConvertable { | |
| fun toJSON(): String = gson.toJson(this) | |
| } | |
| inline fun <reified T: JSONConvertable> String.toObject(): T = gson.fromJson(this, T::class.java) |
| ) : JSONConvertable | ||
|
|
||
| interface JSONConvertable { | ||
| fun toJSON(): String = Gson().toJson(this) | ||
| } | ||
|
|
||
| inline fun <reified T: JSONConvertable> String.toObject(): T = Gson().fromJson(this, T::class.java) |
There was a problem hiding this comment.
Corrected spelling of 'Convertable' to 'Convertible'.
| ) : JSONConvertable | |
| interface JSONConvertable { | |
| fun toJSON(): String = Gson().toJson(this) | |
| } | |
| inline fun <reified T: JSONConvertable> String.toObject(): T = Gson().fromJson(this, T::class.java) | |
| ) : JSONConvertible | |
| interface JSONConvertible { | |
| fun toJSON(): String = Gson().toJson(this) | |
| } | |
| inline fun <reified T: JSONConvertible> String.toObject(): T = Gson().fromJson(this, T::class.java) |
UserInfo fields with snake_case JSON keys (preferred_username, given_name, family_name, updated_at) were silently deserializing as null because Gson performs exact name matching against the camelCase Kotlin property names. Also changes updatedAt from String? to Long? to match the OIDC spec (updated_at is a Unix epoch timestamp), adds ProGuard consumer rules to prevent R8 from stripping Gson model fields, and adds deserialization tests. Supersedes #6, #13, #16. [no-ado]
|
Thanks for the fix — the A couple of concerns:
I've opened PR #23 which combines the annotation fixes from this PR, PR #6, and PR #16, with the correct type, ProGuard rules, and tests. |
The preferred_username, updated_at, given_name and family_name fields captured as null on the userinfo object. This is due to a failure on gson.fromJson conversion for fields with underscores.
Proposing adding annotation for resolving this issue.
Best Regards
James