Skip to content

Commit 243616f

Browse files
authored
Merge pull request #259 from samtstern/master
Handle invalid credentials coming from SmartLock
2 parents cd5fc16 + 22c879a commit 243616f

File tree

2 files changed

+70
-33
lines changed

2 files changed

+70
-33
lines changed

auth/src/main/java/com/firebase/ui/auth/ui/ChooseAccountActivity.java

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
package com.firebase.ui.auth.ui;
1616

17-
import android.app.Activity;
1817
import android.content.Context;
1918
import android.content.DialogInterface;
2019
import android.content.Intent;
@@ -28,16 +27,20 @@
2827
import com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity;
2928
import com.firebase.ui.auth.ui.idp.IDPSignInContainerActivity;
3029
import com.firebase.ui.auth.util.CredentialsAPI;
30+
import com.firebase.ui.auth.util.CredentialsApiHelper;
3131
import com.firebase.ui.auth.util.EmailFlowUtil;
3232
import com.firebase.ui.auth.util.PlayServicesHelper;
3333
import com.google.android.gms.auth.api.credentials.Credential;
3434
import com.google.android.gms.auth.api.credentials.IdentityProviders;
35+
import com.google.android.gms.common.api.Status;
3536
import com.google.android.gms.tasks.OnCompleteListener;
37+
import com.google.android.gms.tasks.OnFailureListener;
3638
import com.google.android.gms.tasks.OnSuccessListener;
3739
import com.google.android.gms.tasks.Task;
3840
import com.google.firebase.auth.AuthResult;
3941
import com.google.firebase.auth.EmailAuthProvider;
4042
import com.google.firebase.auth.FacebookAuthProvider;
43+
import com.google.firebase.auth.FirebaseAuthInvalidUserException;
4144
import com.google.firebase.auth.GoogleAuthProvider;
4245

4346
import java.util.List;
@@ -122,22 +125,12 @@ public void onCredentialsApiConnected(
122125
&& PlayServicesHelper.isPlayServicesAvailable(this)
123126
&& credentialsApi.isCredentialsAvailable()) {
124127

128+
// Attempt auto-sign in using SmartLock
125129
if (credentialsApi.isAutoSignInAvailable()) {
126130
credentialsApi.googleSilentSignIn();
127-
// TODO: (serikb) authenticate Firebase user and continue to application
128131
if (!TextUtils.isEmpty(password)) {
129-
// login with username/password
130-
activityHelper
131-
.getFirebaseAuth()
132-
.signInWithEmailAndPassword(email, password)
133-
.addOnFailureListener(new TaskFailureLogger(
134-
TAG, "Unsuccessful sign in with email and password"))
135-
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
136-
@Override
137-
public void onSuccess(AuthResult authResult) {
138-
finish(Activity.RESULT_OK, new Intent());
139-
}
140-
});
132+
// Sign in with the email/password retrieved from SmartLock
133+
signInWithEmailAndPassword(email, password);
141134
} else {
142135
// log in with id/provider
143136
redirectToIdpSignIn(email, accountType);
@@ -156,6 +149,8 @@ public void onSuccess(AuthResult authResult) {
156149
private void startAuthMethodChoice(ActivityHelper activityHelper) {
157150
List<IDPProviderParcel> providers = activityHelper.getFlowParams().providerInfo;
158151

152+
// If the only provider is Email, immediately launch the email flow. Otherwise, launch
153+
// the auth method picker screen.
159154
if (providers.size() == 1
160155
&& providers.get(0).getProviderType().equals(EmailAuthProvider.PROVIDER_ID)) {
161156
startActivityForResult(
@@ -182,25 +177,7 @@ private void logInWithCredential(
182177
&& !mCredentialsApi.isSignInResolutionNeeded()) {
183178
if (password != null && !password.isEmpty()) {
184179
// email/password combination
185-
mActivityHelper.getFirebaseAuth().signInWithEmailAndPassword(email, password)
186-
.addOnFailureListener(new TaskFailureLogger(
187-
TAG, "Error signing in with email and password"))
188-
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
189-
@Override
190-
public void onComplete(@NonNull Task<AuthResult> task) {
191-
if (task.isSuccessful()) {
192-
finish(RESULT_OK, new Intent());
193-
} else {
194-
// email/password auth failed, go to the
195-
// AuthMethodPickerActivity
196-
startActivityForResult(
197-
AuthMethodPickerActivity.createIntent(
198-
ChooseAccountActivity.this,
199-
mActivityHelper.getFlowParams()),
200-
RC_AUTH_METHOD_PICKER);
201-
}
202-
}
203-
});
180+
signInWithEmailAndPassword(email, password);
204181
} else {
205182
// identifier/provider combination
206183
redirectToIdpSignIn(email, accountType);
@@ -248,6 +225,62 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
248225
}
249226
}
250227

228+
/**
229+
* Begin sign in process with email and password from a SmartLock credential.
230+
* On success, finish with {@link #RESULT_OK}.
231+
* On failure, delete the credential from SmartLock (if applicable) and then launch the
232+
* auth method picker flow.
233+
*/
234+
private void signInWithEmailAndPassword(String email, String password) {
235+
mActivityHelper.getFirebaseAuth()
236+
.signInWithEmailAndPassword(email, password)
237+
.addOnFailureListener(new TaskFailureLogger(
238+
TAG, "Error signing in with email and password"))
239+
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
240+
@Override
241+
public void onSuccess(AuthResult authResult) {
242+
finish(RESULT_OK, new Intent());
243+
}
244+
})
245+
.addOnFailureListener(new OnFailureListener() {
246+
@Override
247+
public void onFailure(@NonNull Exception e) {
248+
if (e instanceof FirebaseAuthInvalidUserException) {
249+
// In this case the credential saved in SmartLock was not
250+
// a valid credential, we should delete it from SmartLock
251+
// before continuing.
252+
deleteCredentialAndRedirect();
253+
} else {
254+
startAuthMethodChoice(mActivityHelper);
255+
}
256+
}
257+
});
258+
}
259+
260+
/**
261+
* Delete the last credential retrieved from SmartLock and then redirect to the
262+
* auth method choice flow.
263+
*/
264+
private void deleteCredentialAndRedirect() {
265+
if (mCredentialsApi.getCredential() == null) {
266+
Log.w(TAG, "deleteCredentialAndRedirect: null credential");
267+
startAuthMethodChoice(mActivityHelper);
268+
return;
269+
}
270+
271+
CredentialsApiHelper credentialsApiHelper = CredentialsApiHelper.getInstance(this);
272+
credentialsApiHelper.delete(mCredentialsApi.getCredential())
273+
.addOnCompleteListener(this, new OnCompleteListener<Status>() {
274+
@Override
275+
public void onComplete(@NonNull Task<Status> task) {
276+
if (!task.isSuccessful()) {
277+
Log.w(TAG, "deleteCredential:failure", task.getException());
278+
}
279+
startAuthMethodChoice(mActivityHelper);
280+
}
281+
});
282+
}
283+
251284
protected void redirectToIdpSignIn(String email, String accountType) {
252285
Intent nextIntent;
253286
switch (accountType) {

auth/src/main/java/com/firebase/ui/auth/util/CredentialsAPI.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ public void resolveSavedEmails(Activity activity) {
9999
}
100100
}
101101

102+
public Credential getCredential() {
103+
return mCredential;
104+
}
105+
102106
public String getEmailFromCredential() {
103107
if (mCredential == null) {
104108
return null;

0 commit comments

Comments
 (0)