Skip to content

Commit 2631d09

Browse files
lsiracsamtstern
authored andcommitted
Adds continue as guest (#1375)
1 parent 9f257b6 commit 2631d09

File tree

20 files changed

+308
-19
lines changed

20 files changed

+308
-19
lines changed

app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public class AuthUiActivity extends AppCompatActivity {
7070
@BindView(R.id.github_provider) CheckBox mUseGitHubProvider;
7171
@BindView(R.id.email_provider) CheckBox mUseEmailProvider;
7272
@BindView(R.id.phone_provider) CheckBox mUsePhoneProvider;
73+
@BindView(R.id.anonymous_provider) CheckBox mUseAnonymousProvider;
7374

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

323+
if (mUseAnonymousProvider.isChecked()) {
324+
selectedProviders.add(new IdpConfig.AnonymousBuilder().build());
325+
}
326+
322327
return selectedProviders;
323328
}
324329

app/src/main/java/com/firebase/uidemo/auth/SignedInActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ private void populateProfile(@Nullable IdpResponse response) {
164164

165165
List<String> providers = new ArrayList<>();
166166
if (user.getProviderData().isEmpty()) {
167-
providers.add("Anonymous");
167+
providers.add(getString(R.string.providers_anonymous));
168168
} else {
169169
for (UserInfo info : user.getProviderData()) {
170170
switch (info.getProviderId()) {

app/src/main/res/layout/auth_ui_layout.xml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@
3434
style="@style/Widget.AppCompat.Button.Colored"
3535
android:layout_width="wrap_content"
3636
android:layout_height="wrap_content"
37-
android:layout_gravity="center"
3837
android:layout_marginTop="16dp"
38+
android:layout_gravity="center"
3939
android:text="@string/sign_in_start" />
4040

4141
<Button
4242
android:id="@+id/sign_in_silent"
4343
style="@style/Widget.AppCompat.Button.Colored"
4444
android:layout_width="wrap_content"
4545
android:layout_height="wrap_content"
46-
android:layout_gravity="center"
4746
android:layout_marginBottom="16dp"
47+
android:layout_gravity="center"
4848
android:text="@string/sign_in_silent" />
4949

5050
<TextView
@@ -80,7 +80,7 @@
8080
android:layout_width="wrap_content"
8181
android:layout_height="wrap_content"
8282
android:checked="true"
83-
android:text="@string/providers_github"/>
83+
android:text="@string/providers_github" />
8484

8585
<CheckBox
8686
android:id="@+id/email_provider"
@@ -96,6 +96,13 @@
9696
android:checked="true"
9797
android:text="@string/providers_phone" />
9898

99+
<CheckBox
100+
android:id="@+id/anonymous_provider"
101+
android:layout_width="wrap_content"
102+
android:layout_height="wrap_content"
103+
android:checked="true"
104+
android:text="@string/providers_anonymous" />
105+
99106
<TextView
100107
style="@style/Base.TextAppearance.AppCompat.Subhead"
101108
android:layout_width="wrap_content"

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<string name="providers_twitter">Twitter</string>
2828
<string name="providers_email">Email</string>
2929
<string name="providers_phone">Phone</string>
30+
<string name="providers_anonymous">Anonymous</string>
3031

3132
<string name="theme_header">Theme</string>
3233
<string name="theme_default">Default theme</string>

auth/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ startActivityForResult(
328328
new AuthUI.IdpConfig.TwitterBuilder().build(),
329329
new AuthUI.IdpConfig.GitHubBuilder().build(),
330330
new AuthUI.IdpConfig.EmailBuilder().build(),
331-
new AuthUI.IdpConfig.PhoneBuilder().build()))
331+
new AuthUI.IdpConfig.PhoneBuilder().build(),
332+
new AuthUI.IdpConfig.AnonymousBuilder().build()))
332333
.build(),
333334
RC_SIGN_IN);
334335
```

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,20 @@ public final class AuthUI {
9595
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
9696
public static final String TAG = "AuthUI";
9797

98+
/**
99+
* Provider for anonymous users.
100+
*/
101+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
102+
public static final String ANONYMOUS_PROVIDER = "anonymous";
103+
98104
@StringDef({
99105
GoogleAuthProvider.PROVIDER_ID,
100106
FacebookAuthProvider.PROVIDER_ID,
101107
TwitterAuthProvider.PROVIDER_ID,
102108
GithubAuthProvider.PROVIDER_ID,
103109
EmailAuthProvider.PROVIDER_ID,
104-
PhoneAuthProvider.PROVIDER_ID
110+
PhoneAuthProvider.PROVIDER_ID,
111+
ANONYMOUS_PROVIDER
105112
})
106113
@Retention(RetentionPolicy.SOURCE)
107114
public @interface SupportedProvider {}
@@ -121,7 +128,8 @@ public final class AuthUI {
121128
TwitterAuthProvider.PROVIDER_ID,
122129
GithubAuthProvider.PROVIDER_ID,
123130
EmailAuthProvider.PROVIDER_ID,
124-
PhoneAuthProvider.PROVIDER_ID
131+
PhoneAuthProvider.PROVIDER_ID,
132+
ANONYMOUS_PROVIDER
125133
)));
126134

127135
/**
@@ -990,6 +998,15 @@ public GitHubBuilder setPermissions(@NonNull List<String> permissions) {
990998
return this;
991999
}
9921000
}
1001+
1002+
/**
1003+
* {@link IdpConfig} builder for the Anonymous provider.
1004+
*/
1005+
public static final class AnonymousBuilder extends Builder {
1006+
public AnonymousBuilder() {
1007+
super(ANONYMOUS_PROVIDER);
1008+
}
1009+
}
9931010
}
9941011

9951012
/**
@@ -1066,17 +1083,28 @@ public T setTosAndPrivacyPolicyUrls(@NonNull String tosUrl,
10661083

10671084
/**
10681085
* Specified the set of supported authentication providers. At least one provider must
1069-
* be specified. There may only be one instance of each provider.
1086+
* be specified. There may only be one instance of each provider. Anonymous provider cannot
1087+
* be the only provider specified.
10701088
* <p>
10711089
* <p>If no providers are explicitly specified by calling this method, then the email
10721090
* provider is the default supported provider.
10731091
*
10741092
* @param idpConfigs a list of {@link IdpConfig}s, where each {@link IdpConfig} contains the
10751093
* configuration parameters for the IDP.
10761094
* @see IdpConfig
1095+
*
1096+
* @throws IllegalStateException if anonymous provider is the only specified provider.
10771097
*/
10781098
@NonNull
10791099
public T setAvailableProviders(@NonNull List<IdpConfig> idpConfigs) {
1100+
Preconditions.checkNotNull(idpConfigs, "idpConfigs cannot be null");
1101+
if (idpConfigs.size() == 1 &&
1102+
idpConfigs.get(0).getProviderId().equals(ANONYMOUS_PROVIDER)) {
1103+
throw new IllegalStateException("Sign in as guest cannot be the only sign in " +
1104+
"method. In this case, sign the user in anonymously your self; " +
1105+
"no UI is needed.");
1106+
}
1107+
10801108
mProviders.clear();
10811109

10821110
for (IdpConfig config : idpConfigs) {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.firebase.ui.auth.data.remote;
2+
3+
import android.app.Application;
4+
import android.content.Intent;
5+
import android.support.annotation.NonNull;
6+
import android.support.annotation.Nullable;
7+
import android.support.annotation.RestrictTo;
8+
import android.support.annotation.VisibleForTesting;
9+
10+
import com.firebase.ui.auth.AuthUI;
11+
import com.firebase.ui.auth.IdpResponse;
12+
import com.firebase.ui.auth.data.model.FlowParameters;
13+
import com.firebase.ui.auth.data.model.Resource;
14+
import com.firebase.ui.auth.data.model.User;
15+
import com.firebase.ui.auth.ui.HelperActivityBase;
16+
import com.firebase.ui.auth.viewmodel.ProviderSignInBase;
17+
import com.google.android.gms.tasks.OnFailureListener;
18+
import com.google.android.gms.tasks.OnSuccessListener;
19+
import com.google.firebase.FirebaseApp;
20+
import com.google.firebase.auth.AuthResult;
21+
import com.google.firebase.auth.FirebaseAuth;
22+
23+
24+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
25+
public class AnonymousSignInHandler extends ProviderSignInBase<FlowParameters> {
26+
27+
@VisibleForTesting
28+
public FirebaseAuth mAuth;
29+
30+
public AnonymousSignInHandler(Application application) {
31+
super(application);
32+
}
33+
34+
@Override
35+
protected void onCreate() {
36+
mAuth = getAuth();
37+
}
38+
39+
@Override
40+
public void startSignIn(@NonNull HelperActivityBase activity) {
41+
setResult(Resource.<IdpResponse>forLoading());
42+
43+
// Calling signInAnonymously() will always return the same anonymous user if already
44+
// available. This is enforced by the client SDK.
45+
mAuth.signInAnonymously()
46+
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
47+
@Override
48+
public void onSuccess(AuthResult result) {
49+
setResult(Resource.<IdpResponse>forSuccess(initResponse(
50+
result.getAdditionalUserInfo().isNewUser())));
51+
}
52+
})
53+
.addOnFailureListener(new OnFailureListener() {
54+
@Override
55+
public void onFailure(@NonNull Exception e) {
56+
setResult(Resource.<IdpResponse>forFailure(e));
57+
}
58+
});
59+
60+
}
61+
62+
@Override
63+
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {}
64+
65+
private IdpResponse initResponse(boolean isNewUser) {
66+
return new IdpResponse.Builder(
67+
new User.Builder(AuthUI.ANONYMOUS_PROVIDER, null)
68+
.build())
69+
.setNewUser(isNewUser)
70+
.build();
71+
}
72+
73+
// TODO: We need to centralize the auth logic. ProviderSignInBase classes were originally
74+
// meant to only retrieve remote provider data.
75+
private FirebaseAuth getAuth() {
76+
FirebaseApp app = FirebaseApp.getInstance(getArguments().appName);
77+
return FirebaseAuth.getInstance(app);
78+
}
79+
}

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.firebase.ui.auth.R;
4242
import com.firebase.ui.auth.data.model.FlowParameters;
4343
import com.firebase.ui.auth.data.model.UserCancellationException;
44+
import com.firebase.ui.auth.data.remote.AnonymousSignInHandler;
4445
import com.firebase.ui.auth.data.remote.EmailSignInHandler;
4546
import com.firebase.ui.auth.data.remote.FacebookSignInHandler;
4647
import com.firebase.ui.auth.data.remote.GitHubSignInHandler;
@@ -117,7 +118,7 @@ protected void onFailure(@NonNull Exception e) {
117118
if (e instanceof FirebaseAuthAnonymousUpgradeException) {
118119
finish(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
119120
((FirebaseAuthAnonymousUpgradeException) e).getResponse().toIntent());
120-
} else if ( (!(e instanceof UserCancellationException))) {
121+
} else if ((!(e instanceof UserCancellationException))) {
121122
String text = e instanceof FirebaseUiException ? e.getMessage() :
122123
getString(R.string.fui_error_unknown);
123124
Toast.makeText(AuthMethodPickerActivity.this,
@@ -186,6 +187,13 @@ private void populateIdpList(List<IdpConfig> providerConfigs,
186187

187188
buttonLayout = R.layout.fui_provider_button_phone;
188189
break;
190+
case AuthUI.ANONYMOUS_PROVIDER:
191+
AnonymousSignInHandler anonymous = supplier.get(AnonymousSignInHandler.class);
192+
anonymous.init(getFlowParams());
193+
provider = anonymous;
194+
195+
buttonLayout = R.layout.fui_provider_button_anonymous;
196+
break;
189197
default:
190198
throw new IllegalStateException("Unknown provider: " + providerId);
191199
}
@@ -215,8 +223,9 @@ private void handleResponse(@NonNull IdpResponse response) {
215223
// started.
216224
handler.startSignIn(response);
217225
} else {
218-
// Email or phone: the credentials should have already been saved so simply
219-
// move along.
226+
// Email or phone: the credentials should have already been saved so
227+
// simply move along. Anononymous sign in also does not require any
228+
// other operations.
220229
finish(response.isSuccessful() ? RESULT_OK : RESULT_CANCELED,
221230
response.toIntent());
222231
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<vector
2+
xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
android:width="24dp"
5+
android:height="24dp"
6+
android:viewportHeight="24.0"
7+
android:viewportWidth="24.0"
8+
tools:ignore="InvalidVectorPath">
9+
<path
10+
android:fillColor="#FFFFFF"
11+
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" />
12+
</vector>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3+
<item>
4+
<shape android:shape="rectangle">
5+
<corners android:radius="3dp" />
6+
<solid android:color="@color/fui_buttonShadow" />
7+
</shape>
8+
</item>
9+
<item
10+
android:bottom="@dimen/fui_button_inset_bottom"
11+
android:left="@dimen/fui_button_inset_left"
12+
android:right="@dimen/fui_button_inset_right"
13+
android:top="@dimen/fui_button_inset_top">
14+
<shape android:shape="rectangle">
15+
<corners android:radius="3dp" />
16+
<solid android:color="@color/fui_bgAnonymous" />
17+
</shape>
18+
</item>
19+
</layer-list>

0 commit comments

Comments
 (0)