1414
1515package com .firebase .ui .auth .ui ;
1616
17- import android .app .Activity ;
1817import android .content .Context ;
1918import android .content .DialogInterface ;
2019import android .content .Intent ;
2827import com .firebase .ui .auth .ui .idp .AuthMethodPickerActivity ;
2928import com .firebase .ui .auth .ui .idp .IDPSignInContainerActivity ;
3029import com .firebase .ui .auth .util .CredentialsAPI ;
30+ import com .firebase .ui .auth .util .CredentialsApiHelper ;
3131import com .firebase .ui .auth .util .EmailFlowUtil ;
3232import com .firebase .ui .auth .util .PlayServicesHelper ;
3333import com .google .android .gms .auth .api .credentials .Credential ;
3434import com .google .android .gms .auth .api .credentials .IdentityProviders ;
35+ import com .google .android .gms .common .api .Status ;
3536import com .google .android .gms .tasks .OnCompleteListener ;
37+ import com .google .android .gms .tasks .OnFailureListener ;
3638import com .google .android .gms .tasks .OnSuccessListener ;
3739import com .google .android .gms .tasks .Task ;
3840import com .google .firebase .auth .AuthResult ;
3941import com .google .firebase .auth .EmailAuthProvider ;
4042import com .google .firebase .auth .FacebookAuthProvider ;
43+ import com .google .firebase .auth .FirebaseAuthInvalidUserException ;
4144import com .google .firebase .auth .GoogleAuthProvider ;
4245
4346import 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 ) {
0 commit comments