Skip to content

Commit 704f35b

Browse files
committed
refactor: clear credman state after signOut and user deletion
1 parent 7231cf5 commit 704f35b

File tree

4 files changed

+59
-14
lines changed

4 files changed

+59
-14
lines changed

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

+49-11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import android.content.Context;
1818
import android.content.Intent;
1919
import android.os.Bundle;
20+
import android.os.CancellationSignal;
2021
import android.os.Parcel;
2122
import android.os.Parcelable;
2223
import android.text.TextUtils;
@@ -32,13 +33,15 @@
3233
import com.firebase.ui.auth.util.data.PhoneNumberUtils;
3334
import com.firebase.ui.auth.util.data.ProviderAvailability;
3435
import com.firebase.ui.auth.util.data.ProviderUtils;
36+
import com.google.android.gms.auth.api.identity.Identity;
3537
import com.google.android.gms.auth.api.signin.GoogleSignIn;
3638
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
3739
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
3840
import com.google.android.gms.common.api.ApiException;
3941
import com.google.android.gms.common.api.CommonStatusCodes;
4042
import com.google.android.gms.common.api.Scope;
4143
import com.google.android.gms.tasks.Task;
44+
import com.google.android.gms.tasks.TaskCompletionSource;
4245
import com.google.android.gms.tasks.Tasks;
4346
import com.google.firebase.FirebaseApp;
4447
import com.google.firebase.auth.ActionCodeSettings;
@@ -68,6 +71,8 @@
6871
import java.util.Locale;
6972
import java.util.Map;
7073
import java.util.Set;
74+
import java.util.concurrent.Executor;
75+
import java.util.concurrent.Executors;
7176

7277
import androidx.annotation.CallSuper;
7378
import androidx.annotation.DrawableRes;
@@ -76,6 +81,9 @@
7681
import androidx.annotation.RestrictTo;
7782
import androidx.annotation.StringDef;
7883
import androidx.annotation.StyleRes;
84+
import androidx.credentials.ClearCredentialStateRequest;
85+
import androidx.credentials.CredentialManagerCallback;
86+
import androidx.credentials.exceptions.ClearCredentialException;
7987

8088
/**
8189
* The entry point to the AuthUI authentication flow, and related utility methods. If your
@@ -280,8 +288,9 @@ public Task<Void> signOut(@NonNull Context context) {
280288
if (!playServicesAvailable) {
281289
Log.w(TAG, "Google Play services not available during signOut");
282290
}
283-
284-
return signOutIdps(context).continueWith(task -> {
291+
signOutIdps(context);
292+
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
293+
return clearCredentialState(context, singleThreadExecutor).continueWith(task -> {
285294
task.getResult(); // Propagate exceptions if any.
286295
mAuth.signOut();
287296
return null;
@@ -303,9 +312,10 @@ public Task<Void> delete(@NonNull final Context context) {
303312
String.valueOf(CommonStatusCodes.SIGN_IN_REQUIRED),
304313
"No currently signed in user."));
305314
}
306-
307-
return signOutIdps(context).continueWithTask(task -> {
308-
task.getResult(); // Propagate exception if there was one.
315+
signOutIdps(context);
316+
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
317+
return clearCredentialState(context, singleThreadExecutor).continueWithTask(task -> {
318+
task.getResult(); // Propagate exceptions if any.
309319
return currentUser.delete();
310320
});
311321
}
@@ -338,15 +348,43 @@ public int getEmulatorPort() {
338348
return mEmulatorPort;
339349
}
340350

341-
private Task<Void> signOutIdps(@NonNull Context context) {
351+
private void signOutIdps(@NonNull Context context) {
342352
if (ProviderAvailability.IS_FACEBOOK_AVAILABLE) {
343353
LoginManager.getInstance().logOut();
344354
}
345-
if (GoogleApiUtils.isPlayServicesAvailable(context)) {
346-
return GoogleSignIn.getClient(context, GoogleSignInOptions.DEFAULT_SIGN_IN).signOut();
347-
} else {
348-
return Tasks.forResult((Void) null);
349-
}
355+
}
356+
357+
/**
358+
* A Task to clear the credential state in Credential Manager.
359+
* @param context
360+
* @param executor
361+
* @return
362+
*/
363+
private Task<Void> clearCredentialState(
364+
@NonNull Context context,
365+
@NonNull Executor executor
366+
) {
367+
TaskCompletionSource<Void> completionSource = new TaskCompletionSource<>();
368+
369+
ClearCredentialStateRequest clearRequest = new ClearCredentialStateRequest();
370+
GoogleApiUtils.getCredentialManager(context)
371+
.clearCredentialStateAsync(
372+
clearRequest,
373+
new CancellationSignal(),
374+
executor,
375+
new CredentialManagerCallback<>() {
376+
@Override
377+
public void onResult(Void unused) {
378+
completionSource.setResult(unused);
379+
}
380+
381+
@Override
382+
public void onError(@NonNull ClearCredentialException e) {
383+
completionSource.setException(e);
384+
}
385+
}
386+
);
387+
return completionSource.getTask();
350388
}
351389

352390
/**

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ import androidx.credentials.exceptions.GetCredentialException
8686
import com.firebase.ui.auth.AuthUI.EMAIL_LINK_PROVIDER
8787
import com.firebase.ui.auth.util.ExtraConstants.GENERIC_OAUTH_BUTTON_ID
8888
import com.firebase.ui.auth.util.ExtraConstants.GENERIC_OAUTH_PROVIDER_ID
89+
import com.firebase.ui.auth.util.GoogleApiUtils
8990
import com.google.android.libraries.identity.googleid.GetGoogleIdOption
9091
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
9192
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException
@@ -105,7 +106,7 @@ class AuthMethodPickerActivity : AppCompatBase() {
105106
// For demonstration, assume that CredentialManager provides a create() method.
106107
private val credentialManager by lazy {
107108
// Replace with your actual CredentialManager instance creation.
108-
CredentialManager.create(this)
109+
GoogleApiUtils.getCredentialManager(this)
109110
}
110111

111112
companion object {

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

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import androidx.annotation.NonNull;
1111
import androidx.annotation.RestrictTo;
12+
import androidx.credentials.CredentialManager;
1213

1314
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
1415
public final class GoogleApiUtils {
@@ -25,4 +26,9 @@ public static boolean isPlayServicesAvailable(@NonNull Context context) {
2526
public static SignInClient getSignInClient(@NonNull Context context) {
2627
return Identity.getSignInClient(context);
2728
}
29+
30+
@NonNull
31+
public static CredentialManager getCredentialManager(@NonNull Context context) {
32+
return CredentialManager.create(context);
33+
}
2834
}

auth/src/main/java/com/firebase/ui/auth/viewmodel/credentialmanager/CredentialManagerHandler.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@ import android.app.Application
44
import android.content.Context
55
import androidx.lifecycle.viewModelScope
66
import androidx.credentials.CreatePasswordRequest
7-
import androidx.credentials.CredentialManager
87
import androidx.credentials.CreateCredentialResponse
98
import androidx.credentials.exceptions.CreateCredentialException
109
import com.firebase.ui.auth.ErrorCodes
1110
import com.firebase.ui.auth.FirebaseUiException
1211
import com.firebase.ui.auth.IdpResponse
1312
import com.firebase.ui.auth.data.model.Resource
13+
import com.firebase.ui.auth.util.GoogleApiUtils
1414
import com.firebase.ui.auth.viewmodel.AuthViewModelBase
1515
import com.google.firebase.auth.FirebaseUser
1616
import kotlinx.coroutines.launch
1717

1818
class CredentialManagerHandler(application: Application) :
1919
AuthViewModelBase<IdpResponse>(application) {
2020

21-
private val credentialManager = CredentialManager.create(application)
21+
private val credentialManager = GoogleApiUtils.getCredentialManager(application)
2222
private var response: IdpResponse? = null
2323

2424
fun setResponse(newResponse: IdpResponse) {

0 commit comments

Comments
 (0)