Skip to content

add option to specify a default provider to skip the selection screen #1829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion auth/src/main/java/com/firebase/ui/auth/AuthUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,7 @@ public GenericOAuthProviderBuilder setCustomParameters(
@SuppressWarnings(value = "unchecked")
private abstract class AuthIntentBuilder<T extends AuthIntentBuilder> {
final List<IdpConfig> mProviders = new ArrayList<>();
IdpConfig mDefaultProvider = null;
int mLogo = NO_LOGO;
int mTheme = getDefaultTheme();
String mTosUrl;
Expand Down Expand Up @@ -1270,7 +1271,7 @@ public T setTosAndPrivacyPolicyUrls(@NonNull String tosUrl,
}

/**
* Specified the set of supported authentication providers. At least one provider must
* Specifies the set of supported authentication providers. At least one provider must
* be specified. There may only be one instance of each provider. Anonymous provider cannot
* be the only provider specified.
* <p>
Expand Down Expand Up @@ -1307,6 +1308,29 @@ public T setAvailableProviders(@NonNull List<IdpConfig> idpConfigs) {
return (T) this;
}

/**
* Specifies the default authentication provider, bypassing the provider selection screen.
* The provider here must already be included via {@link #setAvailableProviders(List)}, and
* this method is incompatible with {@link #setAlwaysShowSignInMethodScreen(boolean)}.
*
* @param config the default {@link IdpConfig} to use.
*/
@NonNull
public T setDefaultProvider(@Nullable IdpConfig config) {
if (config != null) {
if (!mProviders.contains(config)) {
throw new IllegalStateException(
"Default provider not in available providers list.");
}
if (mAlwaysShowProviderChoice) {
throw new IllegalStateException(
"Can't set default provider and always show provider choice.");
}
}
mDefaultProvider = config;
return (T) this;
}

/**
* Enables or disables the use of Smart Lock for Passwords in the sign in flow. To
* (en)disable hint selector and credential selector independently use {@link
Expand Down Expand Up @@ -1359,6 +1383,10 @@ public T setAuthMethodPickerLayout(@NonNull AuthMethodPickerLayout authMethodPic
*/
@NonNull
public T setAlwaysShowSignInMethodScreen(boolean alwaysShow) {
if (alwaysShow && mDefaultProvider != null) {
throw new IllegalStateException(
"Can't show provider choice with a default provider.");
}
mAlwaysShowProviderChoice = alwaysShow;
return (T) this;
}
Expand Down Expand Up @@ -1431,6 +1459,7 @@ protected FlowParameters getFlowParams() {
return new FlowParameters(
mApp.getName(),
mProviders,
mDefaultProvider,
mTheme,
mLogo,
mTosUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class FlowParameters implements Parcelable {
public FlowParameters createFromParcel(Parcel in) {
String appName = in.readString();
List<IdpConfig> providerInfo = in.createTypedArrayList(IdpConfig.CREATOR);
IdpConfig defaultProvider = in.readParcelable(IdpConfig.class.getClassLoader());
int themeId = in.readInt();
int logoId = in.readInt();
String termsOfServiceUrl = in.readString();
Expand All @@ -58,6 +59,7 @@ public FlowParameters createFromParcel(Parcel in) {
return new FlowParameters(
appName,
providerInfo,
defaultProvider,
themeId,
logoId,
termsOfServiceUrl,
Expand All @@ -82,6 +84,9 @@ public FlowParameters[] newArray(int size) {
@NonNull
public final List<IdpConfig> providers;

@Nullable
public final IdpConfig defaultProvider;

@StyleRes
public final int themeId;

Expand All @@ -108,6 +113,7 @@ public FlowParameters[] newArray(int size) {
public FlowParameters(
@NonNull String appName,
@NonNull List<IdpConfig> providers,
@Nullable IdpConfig defaultProvider,
@StyleRes int themeId,
@DrawableRes int logoId,
@Nullable String termsOfServiceUrl,
Expand All @@ -121,6 +127,7 @@ public FlowParameters(
this.appName = Preconditions.checkNotNull(appName, "appName cannot be null");
this.providers = Collections.unmodifiableList(
Preconditions.checkNotNull(providers, "providers cannot be null"));
this.defaultProvider = defaultProvider;
this.themeId = themeId;
this.logoId = logoId;
this.termsOfServiceUrl = termsOfServiceUrl;
Expand All @@ -144,6 +151,7 @@ public static FlowParameters fromIntent(Intent intent) {
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(appName);
dest.writeTypedList(providers);
dest.writeParcelable(defaultProvider, flags);
dest.writeInt(themeId);
dest.writeInt(logoId);
dest.writeString(termsOfServiceUrl);
Expand Down Expand Up @@ -178,6 +186,10 @@ public boolean isAnonymousUpgradeEnabled() {
}

public boolean shouldShowProviderChoice() {
return !isSingleProviderFlow() || alwaysShowProviderChoice;
return defaultProvider == null && (!isSingleProviderFlow() || alwaysShowProviderChoice);
}

public IdpConfig getDefaultOrFirstProvider() {
return defaultProvider != null ? defaultProvider : providers.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,8 @@ public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
}

private void startAuthMethodChoice() {
// If there is only one provider selected, launch the flow directly
if (!getArguments().shouldShowProviderChoice()) {
AuthUI.IdpConfig firstIdpConfig = getArguments().providers.get(0);
AuthUI.IdpConfig firstIdpConfig = getArguments().getDefaultOrFirstProvider();
String firstProvider = firstIdpConfig.getProviderId();
switch (firstProvider) {
case EMAIL_LINK_PROVIDER:
Expand Down
51 changes: 51 additions & 0 deletions auth/src/test/java/com/firebase/ui/auth/AuthUITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

@RunWith(RobolectricTestRunner.class)
public class AuthUITest {
Expand Down Expand Up @@ -65,6 +67,35 @@ public void testCreateStartIntent_shouldOnlyAllowOneInstanceOfAnIdp() {
new IdpConfig.EmailBuilder().build()));
}

@Test(expected = IllegalStateException.class)
public void testCreateStartIntent_defaultProviderMustBeAvailable() {
SignInIntentBuilder startIntent = mAuthUi.createSignInIntentBuilder();
startIntent.setAvailableProviders(Arrays.asList(
new IdpConfig.EmailBuilder().build(),
new IdpConfig.GoogleBuilder().build()))
.setDefaultProvider(new IdpConfig.FacebookBuilder().build());
}

@Test(expected = IllegalStateException.class)
public void testCreateStartIntent_incompatibleOptions() {
SignInIntentBuilder startIntent = mAuthUi.createSignInIntentBuilder();
startIntent.setAvailableProviders(Arrays.asList(
new IdpConfig.EmailBuilder().build(),
new IdpConfig.GoogleBuilder().build()))
.setDefaultProvider(new IdpConfig.GoogleBuilder().build())
.setAlwaysShowSignInMethodScreen(true);
}

@Test(expected = IllegalStateException.class)
public void testCreateStartIntent_incompatibleOptionsReverseOrder() {
SignInIntentBuilder startIntent = mAuthUi.createSignInIntentBuilder();
startIntent.setAvailableProviders(Arrays.asList(
new IdpConfig.EmailBuilder().build(),
new IdpConfig.GoogleBuilder().build()))
.setAlwaysShowSignInMethodScreen(true)
.setDefaultProvider(new IdpConfig.GoogleBuilder().build());
}

@Test
public void testCreatingStartIntent() {
FlowParameters flowParameters = mAuthUi
Expand All @@ -83,6 +114,26 @@ public void testCreatingStartIntent() {
assertEquals(TestConstants.TOS_URL, flowParameters.termsOfServiceUrl);
assertEquals(TestConstants.PRIVACY_URL, flowParameters.privacyPolicyUrl);
assertEquals(AuthUI.getDefaultTheme(), flowParameters.themeId);
assertTrue(flowParameters.shouldShowProviderChoice());
assertEquals(new IdpConfig.EmailBuilder().build(),
flowParameters.getDefaultOrFirstProvider());
}

@Test
public void testCreatingStartIntentWithDefaultProvider() {
FlowParameters flowParameters = mAuthUi
.createSignInIntentBuilder()
.setAvailableProviders(Arrays.asList(
new IdpConfig.EmailBuilder().build(),
new IdpConfig.GoogleBuilder().build(),
new IdpConfig.FacebookBuilder().build()))
.setDefaultProvider(new IdpConfig.FacebookBuilder().build())
.build()
.getParcelableExtra(ExtraConstants.FLOW_PARAMS);
assertEquals(new IdpConfig.FacebookBuilder().build(), flowParameters.defaultProvider);
assertFalse(flowParameters.shouldShowProviderChoice());
assertEquals(new IdpConfig.FacebookBuilder().build(),
flowParameters.getDefaultOrFirstProvider());
}

@Test(expected = NullPointerException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ public static FlowParameters getFlowParameters(Collection<String> providerIds,
return new FlowParameters(
DEFAULT_APP_NAME,
idpConfigs,
null,
AuthUI.getDefaultTheme(),
AuthUI.NO_LOGO,
null,
Expand Down