Skip to content

Commit deec96f

Browse files
committed
working??
1 parent 84d0181 commit deec96f

File tree

2 files changed

+127
-117
lines changed

2 files changed

+127
-117
lines changed

auth/src/main/java/com/firebase/ui/auth/data/remote/SignInKickstarter.kt

Lines changed: 124 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -29,129 +29,134 @@ import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException
2929
import com.google.firebase.auth.FirebaseAuthInvalidUserException
3030
import com.google.firebase.auth.GoogleAuthProvider
3131
import com.google.firebase.auth.PhoneAuthProvider
32+
import kotlinx.coroutines.launch
33+
import androidx.lifecycle.viewModelScope
34+
35+
import androidx.credentials.Credential
36+
import androidx.credentials.CustomCredential
37+
import androidx.credentials.GetCredentialRequest
38+
import androidx.credentials.GetPasswordOption
39+
import androidx.credentials.PasswordCredential
40+
import androidx.credentials.PublicKeyCredential
41+
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
42+
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException
43+
44+
45+
private const val TAG = "SignInKickstarter"
3246

3347
class SignInKickstarter(application: Application?) : SignInViewModelBase(application) {
48+
3449
private val app: Application = checkNotNull(application)
3550

51+
/**
52+
* Entry point. If an email link is detected, immediately launch the email catcher.
53+
* Otherwise, launch startAuthMethodChoice.
54+
*/
3655
fun start() {
3756
if (!TextUtils.isEmpty(arguments.emailLink)) {
3857
setResult(
3958
Resource.forFailure<IdpResponse>(
4059
IntentRequiredException(
41-
EmailLinkCatcherActivity.createIntent(
42-
app,
43-
arguments
44-
),
60+
EmailLinkCatcherActivity.createIntent(app, arguments),
4561
RequestCodes.EMAIL_FLOW
4662
)
4763
)
4864
)
4965
return
5066
}
51-
5267
startAuthMethodChoice()
5368
}
5469

70+
71+
/**
72+
* Fallback: if no credential was obtained (or after a failed Credential Manager attempt)
73+
* choose the proper sign‑in flow.
74+
*/
5575
private fun startAuthMethodChoice() {
5676
if (!arguments.shouldShowProviderChoice()) {
5777
val firstIdpConfig = arguments.defaultOrFirstProvider
5878
val firstProvider = firstIdpConfig.providerId
5979
when (firstProvider) {
60-
AuthUI.EMAIL_LINK_PROVIDER, EmailAuthProvider.PROVIDER_ID -> setResult(
61-
Resource.forFailure<IdpResponse>(
62-
IntentRequiredException(
63-
EmailActivity.createIntent(app, arguments),
64-
RequestCodes.EMAIL_FLOW
80+
AuthUI.EMAIL_LINK_PROVIDER, EmailAuthProvider.PROVIDER_ID ->
81+
setResult(
82+
Resource.forFailure<IdpResponse>(
83+
IntentRequiredException(
84+
EmailActivity.createIntent(app, arguments),
85+
RequestCodes.EMAIL_FLOW
86+
)
6587
)
6688
)
67-
)
68-
69-
PhoneAuthProvider.PROVIDER_ID -> setResult(
70-
Resource.forFailure<IdpResponse>(
71-
IntentRequiredException(
72-
PhoneActivity.createIntent(
73-
app,
74-
arguments, firstIdpConfig.params
75-
),
76-
RequestCodes.PHONE_FLOW
89+
PhoneAuthProvider.PROVIDER_ID ->
90+
setResult(
91+
Resource.forFailure<IdpResponse>(
92+
IntentRequiredException(
93+
PhoneActivity.createIntent(app, arguments, firstIdpConfig.params),
94+
RequestCodes.PHONE_FLOW
95+
)
7796
)
7897
)
79-
)
80-
8198
else -> redirectSignIn(firstProvider, null)
8299
}
83100
} else {
84101
setResult(
85102
Resource.forFailure<IdpResponse>(
86103
IntentRequiredException(
87-
AuthMethodPickerActivity.createIntent(
88-
app,
89-
arguments
90-
),
104+
AuthMethodPickerActivity.createIntent(app, arguments),
91105
RequestCodes.AUTH_PICKER_FLOW
92106
)
93107
)
94108
)
95109
}
96110
}
97111

112+
/**
113+
* Helper to route to the proper sign‑in activity for a given provider.
114+
*/
98115
private fun redirectSignIn(provider: String, id: String?) {
99116
when (provider) {
100-
EmailAuthProvider.PROVIDER_ID -> setResult(
101-
Resource.forFailure<IdpResponse>(
102-
IntentRequiredException(
103-
EmailActivity.createIntent(app, arguments, id),
104-
RequestCodes.EMAIL_FLOW
117+
EmailAuthProvider.PROVIDER_ID ->
118+
setResult(
119+
Resource.forFailure<IdpResponse>(
120+
IntentRequiredException(
121+
EmailActivity.createIntent(app, arguments, id),
122+
RequestCodes.EMAIL_FLOW
123+
)
105124
)
106125
)
107-
)
108-
109126
PhoneAuthProvider.PROVIDER_ID -> {
110-
val args = Bundle()
111-
args.putString(ExtraConstants.PHONE, id)
127+
val args = Bundle().apply { putString(ExtraConstants.PHONE, id) }
112128
setResult(
113129
Resource.forFailure<IdpResponse>(
114130
IntentRequiredException(
115-
PhoneActivity.createIntent(
116-
app,
117-
arguments, args
118-
),
131+
PhoneActivity.createIntent(app, arguments, args),
119132
RequestCodes.PHONE_FLOW
120133
)
121134
)
122135
)
123136
}
124-
125-
else -> setResult(
126-
Resource.forFailure<IdpResponse>(
127-
IntentRequiredException(
128-
SingleSignInActivity.createIntent(
129-
app, arguments,
130-
User.Builder(provider, id).build()
131-
),
132-
RequestCodes.PROVIDER_FLOW
137+
else ->
138+
setResult(
139+
Resource.forFailure<IdpResponse>(
140+
IntentRequiredException(
141+
SingleSignInActivity.createIntent(
142+
app, arguments, User.Builder(provider, id).build()
143+
),
144+
RequestCodes.PROVIDER_FLOW
145+
)
133146
)
134147
)
135-
)
136148
}
137149
}
138150

151+
/**
152+
* Legacy onActivityResult handler for other flows.
153+
*/
139154
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
140155
when (requestCode) {
141-
RequestCodes.CRED_HINT -> if (resultCode == Activity.RESULT_OK && data != null) {
142-
try {
143-
val signInClient = Identity.getSignInClient(app)
144-
val credential = signInClient.getSignInCredentialFromIntent(data)
145-
handleCredential(credential)
146-
} catch (e: ApiException) {
147-
// Optionally log the error
148-
startAuthMethodChoice()
149-
}
150-
} else {
151-
startAuthMethodChoice()
152-
}
153-
154-
RequestCodes.EMAIL_FLOW, RequestCodes.AUTH_PICKER_FLOW, RequestCodes.PHONE_FLOW, RequestCodes.PROVIDER_FLOW -> {
156+
RequestCodes.EMAIL_FLOW,
157+
RequestCodes.AUTH_PICKER_FLOW,
158+
RequestCodes.PHONE_FLOW,
159+
RequestCodes.PROVIDER_FLOW -> {
155160
if (resultCode == RequestCodes.EMAIL_LINK_WRONG_DEVICE_FLOW ||
156161
resultCode == RequestCodes.EMAIL_LINK_INVALID_LINK_FLOW
157162
) {
@@ -163,74 +168,79 @@ class SignInKickstarter(application: Application?) : SignInViewModelBase(applica
163168
setResult(Resource.forFailure(UserCancellationException()))
164169
} else if (response.isSuccessful) {
165170
setResult(Resource.forSuccess(response))
166-
} else if (response.error!!.errorCode ==
167-
ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT
168-
) {
171+
} else if (response.error!!.errorCode == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
169172
handleMergeFailure(response)
170173
} else {
171-
setResult(
172-
Resource.forFailure(
173-
response.error!!
174-
)
175-
)
174+
setResult(Resource.forFailure(response.error!!))
176175
}
177176
}
177+
else -> startAuthMethodChoice()
178178
}
179179
}
180180

181181
/**
182-
* Minimal change: Adapted to work with the new SignInCredential.
182+
* Handle a successfully returned Credential from the Credential Manager.
183183
*/
184-
private fun handleCredential(credential: SignInCredential) {
185-
val id = credential.id
186-
val password = credential.password
187-
if (TextUtils.isEmpty(password)) {
188-
// Instead of checking accountType, check for a Google ID token.
189-
val googleIdToken = credential.googleIdToken
190-
if (!TextUtils.isEmpty(googleIdToken)) {
184+
private fun handleCredentialManagerResult(credential: Credential) {
185+
when (credential) {
186+
is PasswordCredential -> {
187+
val username = credential.id
188+
val password = credential.password
191189
val response = IdpResponse.Builder(
192-
User.Builder(GoogleAuthProvider.PROVIDER_ID, id).build()
190+
User.Builder(EmailAuthProvider.PROVIDER_ID, username).build()
193191
).build()
194192
setResult(Resource.forLoading())
195-
auth.signInWithCredential(GoogleAuthProvider.getCredential(googleIdToken, null))
196-
.addOnSuccessListener { authResult: AuthResult? ->
197-
handleSuccess(
198-
response,
199-
authResult!!
200-
)
193+
auth.signInWithEmailAndPassword(username, password)
194+
.addOnSuccessListener { authResult: AuthResult ->
195+
handleSuccess(response, authResult)
196+
// (Optionally finish the hosting activity here.)
197+
}
198+
.addOnFailureListener { e ->
199+
if (e is FirebaseAuthInvalidUserException ||
200+
e is FirebaseAuthInvalidCredentialsException
201+
) {
202+
// Sign out using the new API.
203+
Identity.getSignInClient(app).signOut()
204+
}
205+
startAuthMethodChoice()
201206
}
202-
.addOnFailureListener { e: Exception? -> startAuthMethodChoice() }
203-
} else {
204-
startAuthMethodChoice()
205207
}
206-
} else {
207-
val response = IdpResponse.Builder(
208-
User.Builder(EmailAuthProvider.PROVIDER_ID, id).build()
209-
).build()
210-
setResult(Resource.forLoading())
211-
auth.signInWithEmailAndPassword(id, password!!)
212-
.addOnSuccessListener { authResult: AuthResult? ->
213-
handleSuccess(
214-
response,
215-
authResult!!
216-
)
217-
}
218-
.addOnFailureListener { e: Exception? ->
219-
if (e is FirebaseAuthInvalidUserException ||
220-
e is FirebaseAuthInvalidCredentialsException
221-
) {
222-
// Minimal change: sign out using the new API (delete isn’t available).
223-
Identity.getSignInClient(
224-
app
208+
is CustomCredential -> {
209+
if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
210+
try {
211+
val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
212+
auth.signInWithCredential(
213+
GoogleAuthProvider.getCredential(googleIdTokenCredential.idToken, null)
225214
)
226-
.signOut()
215+
.addOnSuccessListener { authResult: AuthResult ->
216+
val response = IdpResponse.Builder(
217+
User.Builder(
218+
GoogleAuthProvider.PROVIDER_ID,
219+
// Assume the credential data contains the email.
220+
googleIdTokenCredential.data.getString("email")
221+
).build()
222+
)
223+
.setToken(googleIdTokenCredential.idToken)
224+
.build()
225+
handleSuccess(response, authResult)
226+
}
227+
.addOnFailureListener { e ->
228+
Log.e(TAG, "Failed to sign in with Google ID token", e)
229+
startAuthMethodChoice()
230+
}
231+
} catch (e: GoogleIdTokenParsingException) {
232+
Log.e(TAG, "Received an invalid google id token response", e)
233+
startAuthMethodChoice()
227234
}
235+
} else {
236+
Log.e(TAG, "Unexpected type of credential")
228237
startAuthMethodChoice()
229238
}
239+
}
240+
else -> {
241+
Log.e(TAG, "Unexpected type of credential")
242+
startAuthMethodChoice()
243+
}
230244
}
231245
}
232-
233-
companion object {
234-
private const val TAG = "SignInKickstarter"
235-
}
236-
}
246+
}

auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class AuthMethodPickerActivity : AppCompatBase() {
107107
// Replace with your actual CredentialManager instance creation.
108108
CredentialManager.create(this)
109109
}
110-
110+
111111
companion object {
112112
private const val TAG = "AuthMethodPickerActivity"
113113

@@ -267,8 +267,8 @@ class AuthMethodPickerActivity : AppCompatBase() {
267267
auth.signInWithCredential(GoogleAuthProvider.getCredential(googleIdTokenCredential.idToken, null))
268268
.addOnSuccessListener { authResult ->
269269
val response = IdpResponse.Builder(
270-
User.Builder(GoogleAuthProvider.PROVIDER_ID, googleIdTokenCredential.id).build()
271-
).build()
270+
User.Builder(GoogleAuthProvider.PROVIDER_ID, googleIdTokenCredential.data.getString("email")).build(),
271+
).setToken(googleIdTokenCredential.idToken).build()
272272
KickoffActivity.mKickstarter.handleSuccess(response, authResult)
273273
finish()
274274
}

0 commit comments

Comments
 (0)