Skip to content

Commit

Permalink
Adds continue as guest (#1375)
Browse files Browse the repository at this point in the history
  • Loading branch information
lsirac authored and samtstern committed Jun 29, 2018
1 parent 9f257b6 commit 2631d09
Show file tree
Hide file tree
Showing 20 changed files with 308 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.github_provider) CheckBox mUseGitHubProvider;
@BindView(R.id.email_provider) CheckBox mUseEmailProvider;
@BindView(R.id.phone_provider) CheckBox mUsePhoneProvider;
@BindView(R.id.anonymous_provider) CheckBox mUseAnonymousProvider;

@BindView(R.id.default_theme) RadioButton mDefaultTheme;
@BindView(R.id.green_theme) RadioButton mGreenTheme;
Expand Down Expand Up @@ -319,6 +320,10 @@ private List<IdpConfig> getSelectedProviders() {
selectedProviders.add(new IdpConfig.PhoneBuilder().build());
}

if (mUseAnonymousProvider.isChecked()) {
selectedProviders.add(new IdpConfig.AnonymousBuilder().build());
}

return selectedProviders;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private void populateProfile(@Nullable IdpResponse response) {

List<String> providers = new ArrayList<>();
if (user.getProviderData().isEmpty()) {
providers.add("Anonymous");
providers.add(getString(R.string.providers_anonymous));
} else {
for (UserInfo info : user.getProviderData()) {
switch (info.getProviderId()) {
Expand Down
13 changes: 10 additions & 3 deletions app/src/main/res/layout/auth_ui_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:layout_gravity="center"
android:text="@string/sign_in_start" />

<Button
android:id="@+id/sign_in_silent"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="16dp"
android:layout_gravity="center"
android:text="@string/sign_in_silent" />

<TextView
Expand Down Expand Up @@ -80,7 +80,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/providers_github"/>
android:text="@string/providers_github" />

<CheckBox
android:id="@+id/email_provider"
Expand All @@ -96,6 +96,13 @@
android:checked="true"
android:text="@string/providers_phone" />

<CheckBox
android:id="@+id/anonymous_provider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/providers_anonymous" />

<TextView
style="@style/Base.TextAppearance.AppCompat.Subhead"
android:layout_width="wrap_content"
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<string name="providers_twitter">Twitter</string>
<string name="providers_email">Email</string>
<string name="providers_phone">Phone</string>
<string name="providers_anonymous">Anonymous</string>

<string name="theme_header">Theme</string>
<string name="theme_default">Default theme</string>
Expand Down
3 changes: 2 additions & 1 deletion auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ startActivityForResult(
new AuthUI.IdpConfig.TwitterBuilder().build(),
new AuthUI.IdpConfig.GitHubBuilder().build(),
new AuthUI.IdpConfig.EmailBuilder().build(),
new AuthUI.IdpConfig.PhoneBuilder().build()))
new AuthUI.IdpConfig.PhoneBuilder().build(),
new AuthUI.IdpConfig.AnonymousBuilder().build()))
.build(),
RC_SIGN_IN);
```
Expand Down
34 changes: 31 additions & 3 deletions auth/src/main/java/com/firebase/ui/auth/AuthUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,20 @@ public final class AuthUI {
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static final String TAG = "AuthUI";

/**
* Provider for anonymous users.
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static final String ANONYMOUS_PROVIDER = "anonymous";

@StringDef({
GoogleAuthProvider.PROVIDER_ID,
FacebookAuthProvider.PROVIDER_ID,
TwitterAuthProvider.PROVIDER_ID,
GithubAuthProvider.PROVIDER_ID,
EmailAuthProvider.PROVIDER_ID,
PhoneAuthProvider.PROVIDER_ID
PhoneAuthProvider.PROVIDER_ID,
ANONYMOUS_PROVIDER
})
@Retention(RetentionPolicy.SOURCE)
public @interface SupportedProvider {}
Expand All @@ -121,7 +128,8 @@ public final class AuthUI {
TwitterAuthProvider.PROVIDER_ID,
GithubAuthProvider.PROVIDER_ID,
EmailAuthProvider.PROVIDER_ID,
PhoneAuthProvider.PROVIDER_ID
PhoneAuthProvider.PROVIDER_ID,
ANONYMOUS_PROVIDER
)));

/**
Expand Down Expand Up @@ -990,6 +998,15 @@ public GitHubBuilder setPermissions(@NonNull List<String> permissions) {
return this;
}
}

/**
* {@link IdpConfig} builder for the Anonymous provider.
*/
public static final class AnonymousBuilder extends Builder {
public AnonymousBuilder() {
super(ANONYMOUS_PROVIDER);
}
}
}

/**
Expand Down Expand Up @@ -1066,17 +1083,28 @@ public T setTosAndPrivacyPolicyUrls(@NonNull String tosUrl,

/**
* Specified the set of supported authentication providers. At least one provider must
* be specified. There may only be one instance of each provider.
* be specified. There may only be one instance of each provider. Anonymous provider cannot
* be the only provider specified.
* <p>
* <p>If no providers are explicitly specified by calling this method, then the email
* provider is the default supported provider.
*
* @param idpConfigs a list of {@link IdpConfig}s, where each {@link IdpConfig} contains the
* configuration parameters for the IDP.
* @see IdpConfig
*
* @throws IllegalStateException if anonymous provider is the only specified provider.
*/
@NonNull
public T setAvailableProviders(@NonNull List<IdpConfig> idpConfigs) {
Preconditions.checkNotNull(idpConfigs, "idpConfigs cannot be null");
if (idpConfigs.size() == 1 &&
idpConfigs.get(0).getProviderId().equals(ANONYMOUS_PROVIDER)) {
throw new IllegalStateException("Sign in as guest cannot be the only sign in " +
"method. In this case, sign the user in anonymously your self; " +
"no UI is needed.");
}

mProviders.clear();

for (IdpConfig config : idpConfigs) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.firebase.ui.auth.data.remote;

import android.app.Application;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
import android.support.annotation.VisibleForTesting;

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FlowParameters;
import com.firebase.ui.auth.data.model.Resource;
import com.firebase.ui.auth.data.model.User;
import com.firebase.ui.auth.ui.HelperActivityBase;
import com.firebase.ui.auth.viewmodel.ProviderSignInBase;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseApp;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;


@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class AnonymousSignInHandler extends ProviderSignInBase<FlowParameters> {

@VisibleForTesting
public FirebaseAuth mAuth;

public AnonymousSignInHandler(Application application) {
super(application);
}

@Override
protected void onCreate() {
mAuth = getAuth();
}

@Override
public void startSignIn(@NonNull HelperActivityBase activity) {
setResult(Resource.<IdpResponse>forLoading());

// Calling signInAnonymously() will always return the same anonymous user if already
// available. This is enforced by the client SDK.
mAuth.signInAnonymously()
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult result) {
setResult(Resource.<IdpResponse>forSuccess(initResponse(
result.getAdditionalUserInfo().isNewUser())));
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
setResult(Resource.<IdpResponse>forFailure(e));
}
});

}

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {}

private IdpResponse initResponse(boolean isNewUser) {
return new IdpResponse.Builder(
new User.Builder(AuthUI.ANONYMOUS_PROVIDER, null)
.build())
.setNewUser(isNewUser)
.build();
}

// TODO: We need to centralize the auth logic. ProviderSignInBase classes were originally
// meant to only retrieve remote provider data.
private FirebaseAuth getAuth() {
FirebaseApp app = FirebaseApp.getInstance(getArguments().appName);
return FirebaseAuth.getInstance(app);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.firebase.ui.auth.R;
import com.firebase.ui.auth.data.model.FlowParameters;
import com.firebase.ui.auth.data.model.UserCancellationException;
import com.firebase.ui.auth.data.remote.AnonymousSignInHandler;
import com.firebase.ui.auth.data.remote.EmailSignInHandler;
import com.firebase.ui.auth.data.remote.FacebookSignInHandler;
import com.firebase.ui.auth.data.remote.GitHubSignInHandler;
Expand Down Expand Up @@ -117,7 +118,7 @@ protected void onFailure(@NonNull Exception e) {
if (e instanceof FirebaseAuthAnonymousUpgradeException) {
finish(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
((FirebaseAuthAnonymousUpgradeException) e).getResponse().toIntent());
} else if ( (!(e instanceof UserCancellationException))) {
} else if ((!(e instanceof UserCancellationException))) {
String text = e instanceof FirebaseUiException ? e.getMessage() :
getString(R.string.fui_error_unknown);
Toast.makeText(AuthMethodPickerActivity.this,
Expand Down Expand Up @@ -186,6 +187,13 @@ private void populateIdpList(List<IdpConfig> providerConfigs,

buttonLayout = R.layout.fui_provider_button_phone;
break;
case AuthUI.ANONYMOUS_PROVIDER:
AnonymousSignInHandler anonymous = supplier.get(AnonymousSignInHandler.class);
anonymous.init(getFlowParams());
provider = anonymous;

buttonLayout = R.layout.fui_provider_button_anonymous;
break;
default:
throw new IllegalStateException("Unknown provider: " + providerId);
}
Expand Down Expand Up @@ -215,8 +223,9 @@ private void handleResponse(@NonNull IdpResponse response) {
// started.
handler.startSignIn(response);
} else {
// Email or phone: the credentials should have already been saved so simply
// move along.
// Email or phone: the credentials should have already been saved so
// simply move along. Anononymous sign in also does not require any
// other operations.
finish(response.isSuccessful() ? RESULT_OK : RESULT_CANCELED,
response.toIntent());
}
Expand Down
12 changes: 12 additions & 0 deletions auth/src/main/res/drawable/fui_ic_anonymous_white_24dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
tools:ignore="InvalidVectorPath">
<path
android:fillColor="#FFFFFF"
android:pathData="M12 5.9c1.16 0 2.1.94 2.1 2.1s-0.94 2.1-2.1 2.1S9.9 9.16 9.9 8s0.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-0.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z" />
</vector>
19 changes: 19 additions & 0 deletions auth/src/main/res/drawable/fui_idp_button_background_anonymous.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="@color/fui_buttonShadow" />
</shape>
</item>
<item
android:bottom="@dimen/fui_button_inset_bottom"
android:left="@dimen/fui_button_inset_left"
android:right="@dimen/fui_button_inset_right"
android:top="@dimen/fui_button_inset_top">
<shape android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="@color/fui_bgAnonymous" />
</shape>
</item>
</layer-list>
6 changes: 6 additions & 0 deletions auth/src/main/res/layout/fui_provider_button_anonymous.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<com.firebase.ui.auth.util.ui.SupportVectorDrawablesButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/anonymous_button"
style="@style/FirebaseUI.Button.AccountChooser.AnonymousButton"
android:text="@string/fui_sign_in_anonymously" />
1 change: 1 addition & 0 deletions auth/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
<color name="fui_bgGitHub">#24292E</color>
<color name="fui_bgEmail">#D0021B</color>
<color name="fui_bgPhone">#43C5A5</color>
<color name="fui_bgAnonymous">#f4b400</color>
<color name="fui_buttonShadow">#64BEBEBE</color>
</resources>
1 change: 1 addition & 0 deletions auth/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<string name="fui_sign_in_with_github" translation_description="Sign in button text">Sign in with GitHub</string>
<string name="fui_sign_in_with_email" translation_description="Sign in button text">Sign in with email</string>
<string name="fui_sign_in_with_phone" translation_description="Sign in button text">Sign in with phone</string>
<string name="fui_sign_in_anonymously" translation_description="Continue as guest">Continue as guest</string>

<!-- Email common-->
<string name="fui_next_default" translation_description="Button text to continue">Next</string>
Expand Down
6 changes: 6 additions & 0 deletions auth/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@
<item name="android:textColor">#ffffff</item>
</style>

<style name="FirebaseUI.Button.AccountChooser.AnonymousButton">
<item name="drawableStartCompat">@drawable/fui_ic_anonymous_white_24dp</item>
<item name="android:background">@drawable/fui_idp_button_background_anonymous</item>
<item name="android:textColor">#ffffff</item>
</style>

<style name="FirebaseUI.TopProgressBar" parent="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">4dp</item>
Expand Down
18 changes: 16 additions & 2 deletions auth/src/test/java/com/firebase/ui/auth/AuthUITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,13 @@ public void testCreatingStartIntent() {
.setAvailableProviders(Arrays.asList(
new IdpConfig.EmailBuilder().build(),
new IdpConfig.GoogleBuilder().build(),
new IdpConfig.FacebookBuilder().build()))
new IdpConfig.FacebookBuilder().build(),
new IdpConfig.AnonymousBuilder().build()))
.setTosAndPrivacyPolicyUrls(TestConstants.TOS_URL, TestConstants.PRIVACY_URL)
.build()
.getParcelableExtra(ExtraConstants.FLOW_PARAMS);

assertEquals(3, flowParameters.providerInfo.size());
assertEquals(4, flowParameters.providerInfo.size());
assertEquals(TestHelper.MOCK_APP.getName(), flowParameters.appName);
assertEquals(TestConstants.TOS_URL, flowParameters.termsOfServiceUrl);
assertEquals(TestConstants.PRIVACY_URL, flowParameters.privacyPolicyUrl);
Expand All @@ -93,6 +94,12 @@ public void testCreatingStartIntent_withNullPp_expectEnforcesNonNullPpUrl() {
startIntent.setTosAndPrivacyPolicyUrls(TestConstants.TOS_URL, null);
}

@Test(expected = IllegalStateException.class)
public void testCreatingStartIntent_withOnlyAnonymousProvider_expectIllegalStateException() {
SignInIntentBuilder startIntent = mAuthUi.createSignInIntentBuilder();
startIntent.setAvailableProviders(Arrays.asList(new IdpConfig.AnonymousBuilder().build()));
}

@Test(expected = IllegalArgumentException.class)
public void testPhoneBuilder_withBlacklistedDefaultNumberCode_expectIllegalArgumentException() {
new IdpConfig.PhoneBuilder()
Expand Down Expand Up @@ -202,4 +209,11 @@ public void testPhoneBuilder_passNullForBlacklistedCountries_expectNullPointerEx
.setBlacklistedCountries(null)
.build();
}

@Test
public void testAnonymousBuilder_expectSucess() {
new IdpConfig.AnonymousBuilder()
.build();
}

}
Loading

0 comments on commit 2631d09

Please sign in to comment.