Skip to content

Commit 4e207c0

Browse files
authored
Version 4.3.0
Version 4.3.0
2 parents 3e7fb9e + 37daae0 commit 4e207c0

File tree

161 files changed

+7206
-556
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+7206
-556
lines changed

README.md

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@ libraries.
5050
```groovy
5151
dependencies {
5252
// FirebaseUI for Firebase Realtime Database
53-
implementation 'com.firebaseui:firebase-ui-database:4.2.1'
53+
implementation 'com.firebaseui:firebase-ui-database:4.3.0'
5454
5555
// FirebaseUI for Cloud Firestore
56-
implementation 'com.firebaseui:firebase-ui-firestore:4.2.1'
56+
implementation 'com.firebaseui:firebase-ui-firestore:4.3.0'
5757
5858
// FirebaseUI for Firebase Auth
59-
implementation 'com.firebaseui:firebase-ui-auth:4.2.1'
59+
implementation 'com.firebaseui:firebase-ui-auth:4.3.0'
6060
6161
// FirebaseUI for Firebase Auth (GitHub provider)
62-
implementation 'com.firebaseui:firebase-ui-auth-github:4.2.1'
62+
implementation 'com.firebaseui:firebase-ui-auth-github:4.3.0'
6363
6464
// FirebaseUI for Cloud Storage
65-
implementation 'com.firebaseui:firebase-ui-storage:4.2.1'
65+
implementation 'com.firebaseui:firebase-ui-storage:4.3.0'
6666
}
6767
```
6868

@@ -100,20 +100,8 @@ firebase-ui-storage
100100
|--- com.google.firebase:firebase-storage
101101
```
102102

103-
As of version `15.0.0`, Firebase and Google Play services libraries have independent, semantic
104-
versions. This means that FirebaseUI has independent dependencies on each of the libraries above.
105-
For best results, your app should depend on a version of each dependency with the same major
106-
version number as the version used by FirebaseUI.
107-
108-
As of version `4.2.1`, FirebaseUI has the following dependency versions:
109-
110-
| Library | Version |
111-
|----------------------|--------------------------------|
112-
| `firebase-auth` | 16.0.5 |
113-
| `play-services-auth` | 16.0.1 |
114-
| `firebase-database` | 16.0.3 |
115-
| `firebase-firestore` | 17.1.1 |
116-
| `firebase-storage` | 16.0.3 |
103+
You can see the specific dependencies associated with each release on the
104+
[Releases page][https://github.com/firebase/FirebaseUI-Android/releases].
117105

118106
### Upgrading dependencies
119107

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ dependencies {
5454
// demonstrative purposes, and you may find them useful in your own apps; YMMV.
5555
implementation(Config.Libs.Misc.permissions)
5656
implementation(Config.Libs.Misc.butterKnife)
57+
implementation(Config.Libs.Support.constraint)
5758
annotationProcessor(Config.Libs.Misc.butterKnifeCompiler)
5859
debugImplementation(Config.Libs.Misc.leakCanary)
5960
debugImplementation(Config.Libs.Misc.leakCanaryFragments)

app/src/main/java/com/firebase/uidemo/ChooserActivity.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import android.view.ViewGroup;
2727
import android.widget.TextView;
2828

29+
import com.firebase.ui.auth.AuthUI;
30+
import com.firebase.ui.auth.util.ExtraConstants;
2931
import com.firebase.uidemo.auth.AnonymousUpgradeActivity;
3032
import com.firebase.uidemo.auth.AuthUiActivity;
3133
import com.firebase.uidemo.database.firestore.FirestoreChatActivity;
@@ -43,6 +45,16 @@ public class ChooserActivity extends AppCompatActivity {
4345
@Override
4446
protected void onCreate(@Nullable Bundle savedInstanceState) {
4547
super.onCreate(savedInstanceState);
48+
49+
if (AuthUI.canHandleIntent(getIntent())) {
50+
Intent intent = new Intent(ChooserActivity.this, AuthUiActivity
51+
.class);
52+
intent.putExtra(ExtraConstants.EMAIL_LINK_SIGN_IN, getIntent().getData().toString());
53+
startActivity(intent);
54+
finish();
55+
return;
56+
}
57+
4658
setContentView(R.layout.activity_chooser);
4759
ButterKnife.bind(this);
4860

@@ -51,7 +63,8 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
5163
mActivities.setHasFixedSize(true);
5264
}
5365

54-
private static class ActivityChooserAdapter extends RecyclerView.Adapter<ActivityStarterHolder> {
66+
private static class ActivityChooserAdapter
67+
extends RecyclerView.Adapter<ActivityStarterHolder> {
5568
private static final Class[] CLASSES = new Class[]{
5669
AuthUiActivity.class,
5770
AnonymousUpgradeActivity.class,
@@ -97,7 +110,8 @@ public int getItemCount() {
97110
}
98111
}
99112

100-
private static class ActivityStarterHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
113+
private static class ActivityStarterHolder extends RecyclerView.ViewHolder
114+
implements View.OnClickListener {
101115
private TextView mTitle;
102116
private TextView mDescription;
103117

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

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
5757
super.onCreate(savedInstanceState);
5858
setContentView(R.layout.activity_anonymous_upgrade);
5959
ButterKnife.bind(this);
60+
61+
updateUI();
62+
63+
// Got here from AuthUIActivity, and we need to deal with a merge conflict
64+
// Occurs after catching an email link
65+
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
66+
if (response != null) {
67+
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
68+
getIntent());
69+
}
6070
}
6171

6272
@OnClick(R.id.anon_sign_in)
@@ -81,10 +91,10 @@ public void onComplete(@NonNull Task<AuthResult> task) {
8191
public void startAuthUI() {
8292
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
8393
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
84-
.setLogo(R.drawable.firebase_auth_120dp)
85-
.setAvailableProviders(providers)
86-
.enableAnonymousUsersAutoUpgrade()
87-
.build();
94+
.setLogo(R.drawable.firebase_auth_120dp)
95+
.setAvailableProviders(providers)
96+
.enableAnonymousUsersAutoUpgrade()
97+
.build();
8898
startActivityForResult(intent, RC_SIGN_IN);
8999
}
90100

@@ -105,7 +115,8 @@ public void onComplete(@NonNull Task<AuthResult> task) {
105115
updateUI();
106116

107117
if (task.isSuccessful()) {
108-
setStatus("Signed in as " + getUserIdentifier(task.getResult().getUser()));
118+
setStatus("Signed in as " + getUserIdentifier(task.getResult()
119+
.getUser()));
109120
} else {
110121
Log.w(TAG, "Merge failed", task.getException());
111122
setStatus("Failed to resolve merge conflict, see logs.");
@@ -129,15 +140,21 @@ public void onComplete(@NonNull Task<Void> task) {
129140
@Override
130141
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
131142
super.onActivityResult(requestCode, resultCode, data);
143+
handleSignInResult(requestCode, resultCode, data);
144+
}
145+
146+
private void handleSignInResult(int requestCode, int resultCode, Intent data) {
132147
if (requestCode == RC_SIGN_IN) {
133148
IdpResponse response = IdpResponse.fromResultIntent(data);
134149
if (response == null) {
135150
// User pressed back button
136151
return;
137152
}
138153
if (resultCode == RESULT_OK) {
139-
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance().getCurrentUser()));
140-
} else if (response.getError().getErrorCode() == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
154+
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
155+
.getCurrentUser()));
156+
} else if (response.getError().getErrorCode() == ErrorCodes
157+
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
141158
setStatus("Merge conflict: user already exists.");
142159
mResolveMergeButton.setEnabled(true);
143160
mPendingCredential = response.getCredentialForLinking();

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

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,18 @@
3333
import android.widget.RadioButton;
3434
import android.widget.TextView;
3535

36+
import com.firebase.ui.auth.AuthMethodPickerLayout;
3637
import com.firebase.ui.auth.AuthUI;
3738
import com.firebase.ui.auth.AuthUI.IdpConfig;
3839
import com.firebase.ui.auth.ErrorCodes;
3940
import com.firebase.ui.auth.IdpResponse;
41+
import com.firebase.ui.auth.util.ExtraConstants;
4042
import com.firebase.uidemo.R;
4143
import com.firebase.uidemo.util.ConfigurationUtils;
4244
import com.google.android.gms.common.Scopes;
4345
import com.google.android.gms.tasks.OnCompleteListener;
4446
import com.google.android.gms.tasks.Task;
47+
import com.google.firebase.auth.ActionCodeSettings;
4548
import com.google.firebase.auth.AuthResult;
4649
import com.google.firebase.auth.FirebaseAuth;
4750

@@ -57,8 +60,10 @@ public class AuthUiActivity extends AppCompatActivity {
5760

5861
private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
5962
private static final String FIREBASE_TOS_URL = "https://firebase.google.com/terms/";
60-
private static final String GOOGLE_PRIVACY_POLICY_URL = "https://www.google.com/policies/privacy/";
61-
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google.com/terms/analytics/#7_privacy";
63+
private static final String GOOGLE_PRIVACY_POLICY_URL = "https://www.google" +
64+
".com/policies/privacy/";
65+
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
66+
".com/terms/analytics/#7_privacy";
6267

6368
private static final int RC_SIGN_IN = 100;
6469

@@ -69,9 +74,13 @@ public class AuthUiActivity extends AppCompatActivity {
6974
@BindView(R.id.twitter_provider) CheckBox mUseTwitterProvider;
7075
@BindView(R.id.github_provider) CheckBox mUseGitHubProvider;
7176
@BindView(R.id.email_provider) CheckBox mUseEmailProvider;
77+
@BindView(R.id.email_link_provider) CheckBox mUseEmailLinkProvider;
7278
@BindView(R.id.phone_provider) CheckBox mUsePhoneProvider;
7379
@BindView(R.id.anonymous_provider) CheckBox mUseAnonymousProvider;
7480

81+
@BindView(R.id.default_layout) RadioButton mDefaultLayout;
82+
@BindView(R.id.custom_layout) RadioButton mCustomLayout;
83+
7584
@BindView(R.id.default_theme) RadioButton mDefaultTheme;
7685
@BindView(R.id.green_theme) RadioButton mGreenTheme;
7786
@BindView(R.id.purple_theme) RadioButton mPurpleTheme;
@@ -163,6 +172,41 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
163172
});
164173
}
165174

175+
mUseEmailLinkProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() {
176+
@Override
177+
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
178+
flipPasswordProviderCheckbox(isChecked);
179+
}
180+
});
181+
182+
mUseEmailProvider.setOnCheckedChangeListener(new OnCheckedChangeListener() {
183+
@Override
184+
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
185+
flipEmailLinkProviderCheckbox(isChecked);
186+
}
187+
});
188+
189+
mUseEmailLinkProvider.setChecked(false);
190+
mUseEmailProvider.setChecked(true);
191+
192+
// The custom layout in this app only supports Email and Google providers.
193+
mCustomLayout.setOnCheckedChangeListener(new OnCheckedChangeListener() {
194+
@Override
195+
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
196+
if (checked) {
197+
mUseGoogleProvider.setChecked(true);
198+
mUseEmailProvider.setChecked(true);
199+
200+
mUseFacebookProvider.setChecked(false);
201+
mUseTwitterProvider.setChecked(false);
202+
mUseGitHubProvider.setChecked(false);
203+
mUseEmailLinkProvider.setChecked(false);
204+
mUsePhoneProvider.setChecked(false);
205+
mUseAnonymousProvider.setChecked(false);
206+
}
207+
}
208+
});
209+
166210
if (ConfigurationUtils.isGoogleMisconfigured(this)
167211
|| ConfigurationUtils.isFacebookMisconfigured(this)
168212
|| ConfigurationUtils.isTwitterMisconfigured(this)
@@ -173,24 +217,79 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
173217
if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
174218
mDarkTheme.setChecked(true);
175219
}
220+
221+
catchEmailLinkSignIn();
222+
}
223+
224+
public void catchEmailLinkSignIn() {
225+
if (getIntent().getExtras() == null) {
226+
return;
227+
}
228+
String link = getIntent().getExtras().getString(ExtraConstants.EMAIL_LINK_SIGN_IN);
229+
if (link != null) {
230+
signInWithEmailLink(link);
231+
}
232+
}
233+
234+
public void flipPasswordProviderCheckbox(boolean emailLinkProviderIsChecked) {
235+
if (emailLinkProviderIsChecked) {
236+
mUseEmailProvider.setChecked(false);
237+
}
238+
}
239+
240+
public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {
241+
if (passwordProviderIsChecked) {
242+
mUseEmailLinkProvider.setChecked(false);
243+
}
176244
}
177245

178246
@OnClick(R.id.sign_in)
179247
public void signIn() {
180-
AuthUI.SignInIntentBuilder builder = AuthUI.getInstance().createSignInIntentBuilder()
248+
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
249+
}
250+
251+
public void signInWithEmailLink(@Nullable String link) {
252+
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
253+
}
254+
255+
@NonNull
256+
public Intent buildSignInIntent(@Nullable String link) {
257+
AuthUI.SignInIntentBuilder builder = AuthUI.getInstance().createSignInIntentBuilder()
181258
.setTheme(getSelectedTheme())
182259
.setLogo(getSelectedLogo())
183260
.setAvailableProviders(getSelectedProviders())
184261
.setIsSmartLockEnabled(mEnableCredentialSelector.isChecked(),
185262
mEnableHintSelector.isChecked());
186263

264+
if (mCustomLayout.isChecked()) {
265+
AuthMethodPickerLayout customLayout = new AuthMethodPickerLayout
266+
.Builder(R.layout.auth_method_picker_custom_layout)
267+
.setGoogleButtonId(R.id.custom_google_signin_button)
268+
.setEmailButtonId(R.id.custom_email_signin_clickable_text)
269+
.setTosAndPrivacyPolicyId(R.id.custom_tos_pp)
270+
.build();
271+
272+
builder.setTheme(R.style.CustomTheme);
273+
builder.setAuthMethodPickerLayout(customLayout);
274+
}
275+
187276
if (getSelectedTosUrl() != null && getSelectedPrivacyPolicyUrl() != null) {
188277
builder.setTosAndPrivacyPolicyUrls(
189278
getSelectedTosUrl(),
190279
getSelectedPrivacyPolicyUrl());
191280
}
192281

193-
startActivityForResult(builder.build(), RC_SIGN_IN);
282+
if (link != null) {
283+
builder.setEmailLink(link);
284+
}
285+
286+
FirebaseAuth auth = FirebaseAuth.getInstance();
287+
288+
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
289+
builder.enableAnonymousUsersAutoUpgrade();
290+
}
291+
292+
return builder.build();
194293
}
195294

196295
@OnClick(R.id.sign_in_silent)
@@ -220,7 +319,7 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten
220319
protected void onResume() {
221320
super.onResume();
222321
FirebaseAuth auth = FirebaseAuth.getInstance();
223-
if (auth.getCurrentUser() != null) {
322+
if (auth.getCurrentUser() != null && getIntent().getExtras() == null) {
224323
startSignedInActivity(null);
225324
finish();
226325
}
@@ -246,6 +345,12 @@ private void handleSignInResponse(int resultCode, @Nullable Intent data) {
246345
return;
247346
}
248347

348+
if (response.getError().getErrorCode() == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
349+
Intent intent = new Intent(this, AnonymousUpgradeActivity.class).putExtra
350+
(ExtraConstants.IDP_RESPONSE, response);
351+
startActivity(intent);
352+
}
353+
249354
showSnackbar(R.string.unknown_error);
250355
Log.e(TAG, "Sign-in error: ", response.getError());
251356
}
@@ -317,6 +422,20 @@ private List<IdpConfig> getSelectedProviders() {
317422
.build());
318423
}
319424

425+
if (mUseEmailLinkProvider.isChecked()) {
426+
ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder()
427+
.setAndroidPackageName("com.firebase.uidemo", true, null)
428+
.setHandleCodeInApp(true)
429+
.setUrl("https://google.com")
430+
.build();
431+
432+
selectedProviders.add(new IdpConfig.EmailBuilder()
433+
.setAllowNewAccounts(mAllowNewEmailAccounts.isChecked())
434+
.setActionCodeSettings(actionCodeSettings)
435+
.enableEmailLinkSignIn()
436+
.build());
437+
}
438+
320439
if (mUsePhoneProvider.isChecked()) {
321440
selectedProviders.add(new IdpConfig.PhoneBuilder().build());
322441
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
import butterknife.ButterKnife;
5656
import butterknife.OnClick;
5757

58+
import static com.firebase.ui.auth.AuthUI.EMAIL_LINK_PROVIDER;
59+
5860
public class SignedInActivity extends AppCompatActivity {
5961
private static final String TAG = "SignedInActivity";
6062

@@ -187,6 +189,9 @@ private void populateProfile(@Nullable IdpResponse response) {
187189
case PhoneAuthProvider.PROVIDER_ID:
188190
providers.add(getString(R.string.providers_phone));
189191
break;
192+
case EMAIL_LINK_PROVIDER:
193+
providers.add(getString(R.string.providers_email_link));
194+
break;
190195
case FirebaseAuthProvider.PROVIDER_ID:
191196
// Ignore this provider, it's not very meaningful
192197
break;

0 commit comments

Comments
 (0)