Skip to content

Add JVM credential sign-in and account linking support - #69

Open
TomislavMladenov wants to merge 2 commits into
GitLiveApp:masterfrom
SiereSoft:jvm-auth-credential-support
Open

TomislavMladenov wants to merge 2 commits into
GitLiveApp:masterfrom
SiereSoft:jvm-auth-credential-support

Conversation

@TomislavMladenov

Copy link
Copy Markdown

No description provided.

@nbransby nbransby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the single commit (43fd115) against master. Six inline comments below, most severe first:

  1. Persisted user restore drops isEmailVerified / lastSignInAt — serializer and JsonObject constructor disagree on key names (FirebaseAuth.kt).
  2. Dispatchers.Default as the default main dispatcher breaks the single-thread ordering guarantee for Handler.post callbacks and changes which thread existing consumers receive callbacks on (FirebasePlatform.kt).
  3. FirebaseUserMetadata timestamps reset on every token refresh because createdAt doubles as token-issue time (FirebaseAuth.kt).
  4. Linking a phone credential never adds "phone" to providerData with the real API response; the test's mock injects a providerId the API doesn't return (FirebaseAuth.kt).
  5. Token-refresh path drops urlFactory, so emulator users hit production hosts after a refresh (FirebaseAuth.kt).
  6. Nit: duplicated token-presence check in GoogleAuthCredential / OAuthCredential.

Items 1, 4 and 5 are small, local fixes. Item 2 is the one worth a design decision before merge, since it silently changes threading behaviour for every existing user of the library.


Generated by Claude Code

Comment thread src/main/java/com/google/firebase/auth/FirebaseAuth.kt Outdated
Comment thread src/main/java/com/google/firebase/FirebasePlatform.kt Outdated
Comment thread src/main/java/com/google/firebase/auth/FirebaseAuth.kt
Comment thread src/main/java/com/google/firebase/auth/FirebaseAuth.kt
Comment thread src/main/java/com/google/firebase/auth/FirebaseAuth.kt
Comment thread src/main/java/com/google/firebase/auth/GoogleAuthCredential.java Outdated

@nbransby nbransby left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed 91a51dd against the six earlier findings. All six are fixed and I've resolved those threads:

  1. Persisted restore now reads both isEmailVerified/emailVerified and lastSignInAt/lastLoginAt, and the restore test asserts the verified flag and both timestamps.
  2. Dispatcher default is back to Dispatchers.Main, which is what Handler and AsyncTask used on master, so existing consumers keep their threading. The new FirebasePlatformDispatcherTest pins the ordering and thread guarantee.
  3. Metadata timestamps are decoupled from token time via the new tokenIssuedAt field, carried through refresh/link/update paths, and persisted. Legacy stored users force a refresh rather than inherit a stale lifetime, which is the conservative choice. getAccessToken also now uses 1000L, closing an int-overflow edge.
  4. Phone provider is appended whenever phoneNumber is present, and the test now uses a realistic phone response with no providerId.
  5. urlFactory is passed on every construction path, and useEmulator() re-targets an already-restored user.
  6. Token check is a single requireOAuthToken helper.

Two non-blocking inline notes left (creation timestamp is 0 in production until getAccountInfo runs, and one dead branch in resolveProviderIds). CI is green on this head. Looks ready to approve from my side.


Generated by Claude Code

displayName: String? = data.getOrElse("displayName") { null }?.jsonPrimitive?.contentOrNull,
phoneNumber: String? = data["phoneNumber"]?.jsonPrimitive?.contentOrNull,
isEmailVerified: Boolean = (data["isEmailVerified"] ?: data["emailVerified"])?.jsonPrimitive?.booleanOrNull ?: false,
createdAt: Long = if ("uid" in data && "tokenIssuedAt" !in data) 0 else data["createdAt"]?.jsonPrimitive?.longOrNull ?: 0,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: the split of createdAt (account) from tokenIssuedAt (token) fixes the refresh bug, and 0 for "unknown" matches the Android SDK. One thing to be aware of: the real accounts:signInWithIdp and accounts:signInWithPhoneNumber responses don't carry createdAt / lastLoginAt (the test mock adds them), so in production metadata.creationTimestamp will be 0 after signInWithCredential until something calls getAccountInfo. signInWithCustomToken already chains updateByGetAccountInfo(); doing the same after credential sign-in (and reading lastLoginAt there too) would populate both fields from the one endpoint that actually returns them. Fine as a follow-up.


Generated by Claude Code

} else {
emptyList()
}
val phoneProvider = if (!isAnonymous && phoneNumber != null) listOf("phone") else emptyList()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: with phoneProvider now always appended when phoneNumber != null, the phoneNumber != null -> listOf("phone") branch in inferred (line 287) is dead and can be dropped.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants