14
14
15
15
package com .firebase .ui .auth .ui ;
16
16
17
- import android .app .Activity ;
18
17
import android .content .Context ;
19
18
import android .content .DialogInterface ;
20
19
import android .content .Intent ;
28
27
import com .firebase .ui .auth .ui .idp .AuthMethodPickerActivity ;
29
28
import com .firebase .ui .auth .ui .idp .IDPSignInContainerActivity ;
30
29
import com .firebase .ui .auth .util .CredentialsAPI ;
30
+ import com .firebase .ui .auth .util .CredentialsApiHelper ;
31
31
import com .firebase .ui .auth .util .EmailFlowUtil ;
32
32
import com .firebase .ui .auth .util .PlayServicesHelper ;
33
33
import com .google .android .gms .auth .api .credentials .Credential ;
34
34
import com .google .android .gms .auth .api .credentials .IdentityProviders ;
35
+ import com .google .android .gms .common .api .Status ;
35
36
import com .google .android .gms .tasks .OnCompleteListener ;
37
+ import com .google .android .gms .tasks .OnFailureListener ;
36
38
import com .google .android .gms .tasks .OnSuccessListener ;
37
39
import com .google .android .gms .tasks .Task ;
38
40
import com .google .firebase .auth .AuthResult ;
39
41
import com .google .firebase .auth .EmailAuthProvider ;
40
42
import com .google .firebase .auth .FacebookAuthProvider ;
43
+ import com .google .firebase .auth .FirebaseAuthInvalidUserException ;
41
44
import com .google .firebase .auth .GoogleAuthProvider ;
42
45
43
46
import java .util .List ;
@@ -122,22 +125,12 @@ public void onCredentialsApiConnected(
122
125
&& PlayServicesHelper .isPlayServicesAvailable (this )
123
126
&& credentialsApi .isCredentialsAvailable ()) {
124
127
128
+ // Attempt auto-sign in using SmartLock
125
129
if (credentialsApi .isAutoSignInAvailable ()) {
126
130
credentialsApi .googleSilentSignIn ();
127
- // TODO: (serikb) authenticate Firebase user and continue to application
128
131
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 );
141
134
} else {
142
135
// log in with id/provider
143
136
redirectToIdpSignIn (email , accountType );
@@ -156,6 +149,8 @@ public void onSuccess(AuthResult authResult) {
156
149
private void startAuthMethodChoice (ActivityHelper activityHelper ) {
157
150
List <IDPProviderParcel > providers = activityHelper .getFlowParams ().providerInfo ;
158
151
152
+ // If the only provider is Email, immediately launch the email flow. Otherwise, launch
153
+ // the auth method picker screen.
159
154
if (providers .size () == 1
160
155
&& providers .get (0 ).getProviderType ().equals (EmailAuthProvider .PROVIDER_ID )) {
161
156
startActivityForResult (
@@ -182,25 +177,7 @@ private void logInWithCredential(
182
177
&& !mCredentialsApi .isSignInResolutionNeeded ()) {
183
178
if (password != null && !password .isEmpty ()) {
184
179
// 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 );
204
181
} else {
205
182
// identifier/provider combination
206
183
redirectToIdpSignIn (email , accountType );
@@ -248,6 +225,62 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
248
225
}
249
226
}
250
227
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
+
251
284
protected void redirectToIdpSignIn (String email , String accountType ) {
252
285
Intent nextIntent ;
253
286
switch (accountType ) {
0 commit comments