Skip to content

Commit d58d913

Browse files
authored
fix(expo-google-signin): return the Google account sub as user.id on Android (#9606)
1 parent 58db057 commit d58d913

2 files changed

Lines changed: 17 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/expo-google-signin': patch
3+
---
4+
5+
Android now reports the Google account's stable identifier (the ID token's `sub` claim) as `user.id` instead of the email address, matching iOS.

packages/expo-google-signin/android/src/main/java/expo/modules/clerk/googlesignin/ClerkGoogleSignInModule.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package expo.modules.clerk.googlesignin
22

3+
import android.util.Base64
34
import androidx.credentials.ClearCredentialStateRequest
45
import androidx.credentials.CredentialManager
56
import androidx.credentials.CustomCredential
@@ -18,6 +19,7 @@ import expo.modules.kotlin.modules.ModuleDefinition
1819
import kotlinx.coroutines.CoroutineScope
1920
import kotlinx.coroutines.Dispatchers
2021
import kotlinx.coroutines.launch
22+
import org.json.JSONObject
2123

2224
class ClerkGoogleSignInModule : Module() {
2325
private var webClientId: String? = null
@@ -221,6 +223,15 @@ class ClerkGoogleSignInModule : Module() {
221223
promise.reject("SIGN_IN_CANCELLED", exception.message ?: "User cancelled the sign-in flow", exception)
222224
}
223225

226+
// GoogleIdTokenCredential.id is the email, so the stable account ID has to come from the token's sub claim.
227+
private fun subjectFromIdToken(idToken: String): String? {
228+
val payload = idToken.split(".").getOrNull(1) ?: return null
229+
return runCatching {
230+
val json = String(Base64.decode(payload, Base64.URL_SAFE or Base64.NO_WRAP or Base64.NO_PADDING))
231+
JSONObject(json).optString("sub").takeIf { it.isNotEmpty() }
232+
}.getOrNull()
233+
}
234+
224235
private fun handleSignInResult(result: GetCredentialResponse, promise: Promise) {
225236
when (val credential = result.credential) {
226237
is CustomCredential -> {
@@ -229,7 +240,7 @@ class ClerkGoogleSignInModule : Module() {
229240
val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
230241

231242
val user = mapOf(
232-
"id" to googleIdTokenCredential.id,
243+
"id" to (subjectFromIdToken(googleIdTokenCredential.idToken) ?: ""),
233244
"email" to googleIdTokenCredential.id,
234245
"name" to googleIdTokenCredential.displayName,
235246
"givenName" to googleIdTokenCredential.givenName,

0 commit comments

Comments
 (0)