Skip to content

Commit 1518086

Browse files
committed
Sign In working
1 parent c45845c commit 1518086

File tree

2 files changed

+150
-98
lines changed

2 files changed

+150
-98
lines changed

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

Lines changed: 83 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.content.Intent;
66
import android.os.Bundle;
77
import android.text.TextUtils;
8+
import android.util.Log;
89

910
import com.firebase.ui.auth.AuthUI;
1011
import com.firebase.ui.auth.ErrorCodes;
@@ -24,15 +25,9 @@
2425
import com.firebase.ui.auth.util.data.ProviderUtils;
2526
import com.firebase.ui.auth.viewmodel.RequestCodes;
2627
import com.firebase.ui.auth.viewmodel.SignInViewModelBase;
27-
import com.google.android.gms.auth.api.credentials.Credential;
28-
import com.google.android.gms.auth.api.credentials.CredentialRequest;
29-
import com.google.android.gms.auth.api.credentials.CredentialRequestResponse;
3028
import com.google.android.gms.common.api.ApiException;
3129
import com.google.android.gms.common.api.CommonStatusCodes;
3230
import com.google.android.gms.common.api.ResolvableApiException;
33-
import com.google.android.gms.tasks.OnCompleteListener;
34-
import com.google.android.gms.tasks.OnFailureListener;
35-
import com.google.android.gms.tasks.OnSuccessListener;
3631
import com.google.android.gms.tasks.Task;
3732
import com.google.firebase.auth.AuthResult;
3833
import com.google.firebase.auth.EmailAuthProvider;
@@ -41,6 +36,12 @@
4136
import com.google.firebase.auth.GoogleAuthProvider;
4237
import com.google.firebase.auth.PhoneAuthProvider;
4338

39+
// Minimal changes: import new API classes
40+
import com.google.android.gms.auth.api.identity.BeginSignInRequest;
41+
import com.google.android.gms.auth.api.identity.SignInClient;
42+
import com.google.android.gms.auth.api.identity.SignInCredential;
43+
import com.google.android.gms.auth.api.identity.Identity;
44+
4445
import java.util.ArrayList;
4546
import java.util.List;
4647

@@ -50,6 +51,8 @@
5051
import static com.firebase.ui.auth.AuthUI.EMAIL_LINK_PROVIDER;
5152

5253
public class SignInKickstarter extends SignInViewModelBase {
54+
private static final String TAG = "SignInKickstarter";
55+
5356
public SignInKickstarter(Application application) {
5457
super(application);
5558
}
@@ -62,58 +65,59 @@ public void start() {
6265
return;
6366
}
6467

65-
// Signing in with Generic IDP puts the app in the background - it can be reclaimed by the
66-
// OS during the sign in flow.
68+
// Signing in with Generic IDP puts the app in the background -
69+
// it can be reclaimed by the OS during the sign in flow.
6770
Task<AuthResult> pendingResultTask = getAuth().getPendingAuthResult();
6871
if (pendingResultTask != null) {
6972
pendingResultTask
70-
.addOnSuccessListener(
71-
authResult -> {
72-
final IdpResponse response = new IdpResponse.Builder(
73-
new User.Builder(
74-
authResult.getCredential().getProvider(),
75-
authResult.getUser().getEmail()).build())
76-
.build();
77-
handleSuccess(response, authResult);
78-
79-
})
80-
.addOnFailureListener(
81-
e -> setResult(Resource.forFailure(e)));
73+
.addOnSuccessListener(authResult -> {
74+
final IdpResponse response = new IdpResponse.Builder(
75+
new User.Builder(
76+
authResult.getCredential().getProvider(),
77+
authResult.getUser().getEmail()).build())
78+
.build();
79+
handleSuccess(response, authResult);
80+
})
81+
.addOnFailureListener(e -> setResult(Resource.forFailure(e)));
8282
return;
8383
}
8484

85-
86-
// Only support password credentials if email auth is enabled
8785
boolean supportPasswords = ProviderUtils.getConfigFromIdps(
8886
getArguments().providers, EmailAuthProvider.PROVIDER_ID) != null;
8987
List<String> accountTypes = getCredentialAccountTypes();
90-
91-
// If the request will be empty, avoid the step entirely
92-
boolean willRequestCredentials = supportPasswords || accountTypes.size() > 0;
88+
boolean willRequestCredentials = supportPasswords || !accountTypes.isEmpty();
9389

9490
if (getArguments().enableCredentials && willRequestCredentials) {
9591
setResult(Resource.forLoading());
9692

97-
GoogleApiUtils.getCredentialsClient(getApplication())
98-
.request(new CredentialRequest.Builder()
99-
.setPasswordLoginSupported(supportPasswords)
100-
.setAccountTypes(accountTypes.toArray(new String[accountTypes.size()]))
101-
.build())
102-
.addOnCompleteListener(task -> {
103-
try {
104-
handleCredential(
105-
task.getResult(ApiException.class).getCredential());
106-
} catch (ResolvableApiException e) {
107-
if (e.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED) {
108-
setResult(Resource.forFailure(
109-
new PendingIntentRequiredException(
110-
e.getResolution(), RequestCodes.CRED_HINT)));
111-
} else {
112-
startAuthMethodChoice();
113-
}
114-
} catch (ApiException e) {
115-
startAuthMethodChoice();
116-
}
93+
// Minimal change: use new SignInClient with BeginSignInRequest.
94+
SignInClient signInClient = Identity.getSignInClient(getApplication());
95+
BeginSignInRequest.Builder requestBuilder = BeginSignInRequest.builder();
96+
if (supportPasswords) {
97+
requestBuilder.setPasswordRequestOptions(
98+
BeginSignInRequest.PasswordRequestOptions.builder()
99+
.setSupported(true)
100+
.build());
101+
}
102+
if (!accountTypes.isEmpty()) {
103+
// For Google Sign-In, set the ID token request options.
104+
requestBuilder.setGoogleIdTokenRequestOptions(
105+
BeginSignInRequest.GoogleIdTokenRequestOptions.builder()
106+
.setSupported(true)
107+
.build());
108+
}
109+
BeginSignInRequest signInRequest = requestBuilder.build();
110+
111+
signInClient.beginSignIn(signInRequest)
112+
.addOnSuccessListener(result -> {
113+
// The new API returns a PendingIntent to launch the sign-in UI.
114+
setResult(Resource.forFailure(
115+
new PendingIntentRequiredException(result.getPendingIntent(), RequestCodes.CRED_HINT)));
116+
})
117+
.addOnFailureListener(e -> {
118+
Log.e(TAG, "beginSignIn failed: " + e);
119+
// Regardless of the error (including error code 16), fallback to the auth method choice.
120+
startAuthMethodChoice();
117121
});
118122
} else {
119123
startAuthMethodChoice();
@@ -133,8 +137,7 @@ private void startAuthMethodChoice() {
133137
break;
134138
case PhoneAuthProvider.PROVIDER_ID:
135139
setResult(Resource.forFailure(new IntentRequiredException(
136-
PhoneActivity.createIntent(
137-
getApplication(), getArguments(), firstIdpConfig.getParams()),
140+
PhoneActivity.createIntent(getApplication(), getArguments(), firstIdpConfig.getParams()),
138141
RequestCodes.PHONE_FLOW)));
139142
break;
140143
default:
@@ -159,17 +162,12 @@ private void redirectSignIn(String provider, String id) {
159162
Bundle args = new Bundle();
160163
args.putString(ExtraConstants.PHONE, id);
161164
setResult(Resource.forFailure(new IntentRequiredException(
162-
PhoneActivity.createIntent(
163-
getApplication(),
164-
getArguments(),
165-
args),
165+
PhoneActivity.createIntent(getApplication(), getArguments(), args),
166166
RequestCodes.PHONE_FLOW)));
167167
break;
168168
default:
169169
setResult(Resource.forFailure(new IntentRequiredException(
170-
SingleSignInActivity.createIntent(
171-
getApplication(),
172-
getArguments(),
170+
SingleSignInActivity.createIntent(getApplication(), getArguments(),
173171
new User.Builder(provider, id).build()),
174172
RequestCodes.PROVIDER_FLOW)));
175173
}
@@ -189,8 +187,15 @@ private List<String> getCredentialAccountTypes() {
189187
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
190188
switch (requestCode) {
191189
case RequestCodes.CRED_HINT:
192-
if (resultCode == Activity.RESULT_OK) {
193-
handleCredential((Credential) data.getParcelableExtra(Credential.EXTRA_KEY));
190+
if (resultCode == Activity.RESULT_OK && data != null) {
191+
try {
192+
SignInClient signInClient = Identity.getSignInClient(getApplication());
193+
SignInCredential credential = signInClient.getSignInCredentialFromIntent(data);
194+
handleCredential(credential);
195+
} catch (ApiException e) {
196+
// Optionally log the error
197+
startAuthMethodChoice();
198+
}
194199
} else {
195200
startAuthMethodChoice();
196201
}
@@ -199,7 +204,8 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d
199204
case RequestCodes.AUTH_PICKER_FLOW:
200205
case RequestCodes.PHONE_FLOW:
201206
case RequestCodes.PROVIDER_FLOW:
202-
if (resultCode == RequestCodes.EMAIL_LINK_WRONG_DEVICE_FLOW || resultCode == RequestCodes.EMAIL_LINK_INVALID_LINK_FLOW) {
207+
if (resultCode == RequestCodes.EMAIL_LINK_WRONG_DEVICE_FLOW ||
208+
resultCode == RequestCodes.EMAIL_LINK_INVALID_LINK_FLOW) {
203209
startAuthMethodChoice();
204210
return;
205211
}
@@ -217,35 +223,39 @@ public void onActivityResult(int requestCode, int resultCode, @Nullable Intent d
217223
}
218224
}
219225

220-
private void handleCredential(final Credential credential) {
226+
/**
227+
* Minimal change: Adapted to work with the new SignInCredential.
228+
*/
229+
private void handleCredential(final SignInCredential credential) {
221230
String id = credential.getId();
222231
String password = credential.getPassword();
223232
if (TextUtils.isEmpty(password)) {
224-
String identity = credential.getAccountType();
225-
if (identity == null) {
226-
startAuthMethodChoice();
233+
// Instead of checking accountType, check for a Google ID token.
234+
String googleIdToken = credential.getGoogleIdToken();
235+
if (!TextUtils.isEmpty(googleIdToken)) {
236+
final IdpResponse response = new IdpResponse.Builder(
237+
new User.Builder(GoogleAuthProvider.PROVIDER_ID, id).build()).build();
238+
setResult(Resource.forLoading());
239+
getAuth().signInWithCredential(GoogleAuthProvider.getCredential(googleIdToken, null))
240+
.addOnSuccessListener(authResult -> handleSuccess(response, authResult))
241+
.addOnFailureListener(e -> startAuthMethodChoice());
227242
} else {
228-
redirectSignIn(
229-
ProviderUtils.accountTypeToProviderId(credential.getAccountType()), id);
243+
startAuthMethodChoice();
230244
}
231245
} else {
232246
final IdpResponse response = new IdpResponse.Builder(
233247
new User.Builder(EmailAuthProvider.PROVIDER_ID, id).build()).build();
234-
235248
setResult(Resource.forLoading());
236249
getAuth().signInWithEmailAndPassword(id, password)
237-
.addOnSuccessListener(result -> handleSuccess(response, result))
250+
.addOnSuccessListener(authResult -> handleSuccess(response, authResult))
238251
.addOnFailureListener(e -> {
239-
if (e instanceof FirebaseAuthInvalidUserException
240-
|| e instanceof FirebaseAuthInvalidCredentialsException) {
241-
// In this case the credential saved in SmartLock was not
242-
// a valid credential, we should delete it from SmartLock
243-
// before continuing.
244-
GoogleApiUtils.getCredentialsClient(getApplication())
245-
.delete(credential);
252+
if (e instanceof FirebaseAuthInvalidUserException ||
253+
e instanceof FirebaseAuthInvalidCredentialsException) {
254+
// Minimal change: sign out using the new API (delete isn’t available).
255+
Identity.getSignInClient(getApplication()).signOut();
246256
}
247257
startAuthMethodChoice();
248258
});
249259
}
250260
}
251-
}
261+
}

auth/src/main/java/com/firebase/ui/auth/ui/email/CheckEmailHandler.java

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,65 @@
22

33
import android.app.Activity;
44
import android.app.Application;
5+
import android.app.PendingIntent;
56
import android.content.Intent;
7+
import android.util.Log;
68

79
import com.firebase.ui.auth.data.model.PendingIntentRequiredException;
810
import com.firebase.ui.auth.data.model.Resource;
911
import com.firebase.ui.auth.data.model.User;
1012
import com.firebase.ui.auth.util.data.ProviderUtils;
1113
import com.firebase.ui.auth.viewmodel.AuthViewModelBase;
1214
import com.firebase.ui.auth.viewmodel.RequestCodes;
13-
import com.google.android.gms.auth.api.credentials.Credential;
14-
import com.google.android.gms.auth.api.credentials.Credentials;
15-
import com.google.android.gms.auth.api.credentials.HintRequest;
16-
import com.google.android.gms.tasks.OnCompleteListener;
15+
import com.google.android.gms.common.api.ApiException;
1716
import com.google.android.gms.tasks.Task;
1817

19-
import androidx.annotation.NonNull;
18+
// New Identity API imports:
19+
import com.google.android.gms.auth.api.identity.BeginSignInRequest;
20+
import com.google.android.gms.auth.api.identity.SignInClient;
21+
import com.google.android.gms.auth.api.identity.SignInCredential;
22+
import com.google.android.gms.auth.api.identity.Identity;
23+
2024
import androidx.annotation.Nullable;
2125

2226
public class CheckEmailHandler extends AuthViewModelBase<User> {
27+
private static final String TAG = "CheckEmailHandler";
28+
2329
public CheckEmailHandler(Application application) {
2430
super(application);
2531
}
2632

33+
/**
34+
* Initiates a hint picker flow using the new Identity API.
35+
* This replaces the deprecated Credentials API call.
36+
*/
2737
public void fetchCredential() {
28-
setResult(Resource.forFailure(new PendingIntentRequiredException(
29-
Credentials.getClient(getApplication()).getHintPickerIntent(
30-
new HintRequest.Builder().setEmailAddressIdentifierSupported(true).build()),
31-
RequestCodes.CRED_HINT
32-
)));
38+
// Build a sign-in request that supports password-based sign in,
39+
// which will trigger the hint picker UI for email addresses.
40+
SignInClient signInClient = Identity.getSignInClient(getApplication());
41+
BeginSignInRequest signInRequest = BeginSignInRequest.builder()
42+
.setPasswordRequestOptions(
43+
BeginSignInRequest.PasswordRequestOptions.builder()
44+
.setSupported(true)
45+
.build())
46+
.build();
47+
48+
signInClient.beginSignIn(signInRequest)
49+
.addOnSuccessListener(result -> {
50+
// The new API returns a PendingIntent to launch the hint picker.
51+
PendingIntent pendingIntent = result.getPendingIntent();
52+
setResult(Resource.forFailure(
53+
new PendingIntentRequiredException(pendingIntent, RequestCodes.CRED_HINT)));
54+
})
55+
.addOnFailureListener(e -> {
56+
Log.e(TAG, "beginSignIn failed", e);
57+
setResult(Resource.forFailure(e));
58+
});
3359
}
3460

61+
/**
62+
* Fetches the top provider for the given email.
63+
*/
3564
public void fetchProvider(final String email) {
3665
setResult(Resource.forLoading());
3766
ProviderUtils.fetchTopProvider(getAuth(), getArguments(), email)
@@ -45,22 +74,35 @@ public void fetchProvider(final String email) {
4574
});
4675
}
4776

77+
/**
78+
* Handles the result from the hint picker launched via the new Identity API.
79+
*/
4880
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
49-
if (requestCode != RequestCodes.CRED_HINT || resultCode != Activity.RESULT_OK) { return; }
81+
if (requestCode != RequestCodes.CRED_HINT || resultCode != Activity.RESULT_OK) {
82+
return;
83+
}
5084

5185
setResult(Resource.forLoading());
52-
final Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
53-
final String email = credential.getId();
54-
ProviderUtils.fetchTopProvider(getAuth(), getArguments(), email)
55-
.addOnCompleteListener(task -> {
56-
if (task.isSuccessful()) {
57-
setResult(Resource.forSuccess(new User.Builder(task.getResult(), email)
58-
.setName(credential.getName())
59-
.setPhotoUri(credential.getProfilePictureUri())
60-
.build()));
61-
} else {
62-
setResult(Resource.forFailure(task.getException()));
63-
}
64-
});
86+
SignInClient signInClient = Identity.getSignInClient(getApplication());
87+
try {
88+
// Retrieve the SignInCredential from the returned intent.
89+
SignInCredential credential = signInClient.getSignInCredentialFromIntent(data);
90+
final String email = credential.getId();
91+
92+
ProviderUtils.fetchTopProvider(getAuth(), getArguments(), email)
93+
.addOnCompleteListener(task -> {
94+
if (task.isSuccessful()) {
95+
setResult(Resource.forSuccess(new User.Builder(task.getResult(), email)
96+
.setName(credential.getDisplayName())
97+
.setPhotoUri(credential.getProfilePictureUri())
98+
.build()));
99+
} else {
100+
setResult(Resource.forFailure(task.getException()));
101+
}
102+
});
103+
} catch (ApiException e) {
104+
Log.e(TAG, "getSignInCredentialFromIntent failed", e);
105+
setResult(Resource.forFailure(e));
106+
}
65107
}
66-
}
108+
}

0 commit comments

Comments
 (0)