Skip to content

Commit 41c7a73

Browse files
authored
Version 7.2.0
Version 7.2.0
2 parents 3d578ef + 4903947 commit 41c7a73

File tree

18 files changed

+215
-87
lines changed

18 files changed

+215
-87
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ libraries.
4848
```groovy
4949
dependencies {
5050
// FirebaseUI for Firebase Realtime Database
51-
implementation 'com.firebaseui:firebase-ui-database:7.1.1'
51+
implementation 'com.firebaseui:firebase-ui-database:7.2.0'
5252
5353
// FirebaseUI for Cloud Firestore
54-
implementation 'com.firebaseui:firebase-ui-firestore:7.1.1'
54+
implementation 'com.firebaseui:firebase-ui-firestore:7.2.0'
5555
5656
// FirebaseUI for Firebase Auth
57-
implementation 'com.firebaseui:firebase-ui-auth:7.1.1'
57+
implementation 'com.firebaseui:firebase-ui-auth:7.2.0'
5858
5959
// FirebaseUI for Cloud Storage
60-
implementation 'com.firebaseui:firebase-ui-storage:7.1.1'
60+
implementation 'com.firebaseui:firebase-ui-storage:7.2.0'
6161
}
6262
```
6363

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

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

1010
import com.firebase.ui.auth.AuthUI;
1111
import com.firebase.ui.auth.ErrorCodes;
12+
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
1213
import com.firebase.ui.auth.IdpResponse;
14+
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
1315
import com.firebase.uidemo.R;
1416
import com.firebase.uidemo.databinding.ActivityAnonymousUpgradeBinding;
1517
import com.firebase.uidemo.util.ConfigurationUtils;
@@ -22,20 +24,24 @@
2224

2325
import java.util.List;
2426

27+
import androidx.activity.result.ActivityResultCallback;
28+
import androidx.activity.result.ActivityResultLauncher;
2529
import androidx.annotation.NonNull;
2630
import androidx.annotation.Nullable;
2731
import androidx.appcompat.app.AppCompatActivity;
2832

29-
public class AnonymousUpgradeActivity extends AppCompatActivity {
33+
public class AnonymousUpgradeActivity extends AppCompatActivity
34+
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
3035

3136
private static final String TAG = "AccountLink";
3237

33-
private static final int RC_SIGN_IN = 123;
34-
3538
private ActivityAnonymousUpgradeBinding mBinding;
3639

3740
private AuthCredential mPendingCredential;
3841

42+
private final ActivityResultLauncher<Intent> signIn =
43+
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);
44+
3945
@Override
4046
protected void onCreate(@Nullable Bundle savedInstanceState) {
4147
super.onCreate(savedInstanceState);
@@ -48,8 +54,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
4854
// Occurs after catching an email link
4955
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
5056
if (response != null) {
51-
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
52-
getIntent());
57+
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
5358
}
5459

5560
mBinding.anonSignIn.setOnClickListener(new View.OnClickListener() {
@@ -100,12 +105,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
100105

101106
public void startAuthUI() {
102107
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
103-
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
108+
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
104109
.setLogo(R.drawable.firebase_auth_120dp)
105110
.setAvailableProviders(providers)
106111
.enableAnonymousUsersAutoUpgrade()
107112
.build();
108-
startActivityForResult(intent, RC_SIGN_IN);
113+
signIn.launch(signInIntent);
109114
}
110115

111116
public void resolveMerge() {
@@ -145,34 +150,25 @@ public void onComplete(@NonNull Task<Void> task) {
145150
});
146151
}
147152

148-
@Override
149-
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
150-
super.onActivityResult(requestCode, resultCode, data);
151-
handleSignInResult(requestCode, resultCode, data);
152-
}
153-
154-
private void handleSignInResult(int requestCode, int resultCode, Intent data) {
155-
if (requestCode == RC_SIGN_IN) {
156-
IdpResponse response = IdpResponse.fromResultIntent(data);
157-
if (response == null) {
158-
// User pressed back button
159-
return;
160-
}
161-
if (resultCode == RESULT_OK) {
162-
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
163-
.getCurrentUser()));
164-
} else if (response.getError().getErrorCode() == ErrorCodes
165-
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
166-
setStatus("Merge conflict: user already exists.");
167-
mBinding.resolveMerge.setEnabled(true);
168-
mPendingCredential = response.getCredentialForLinking();
169-
} else {
170-
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
171-
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
172-
}
173-
174-
updateUI();
153+
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
154+
if (response == null) {
155+
// User pressed back button
156+
return;
175157
}
158+
if (resultCode == RESULT_OK) {
159+
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
160+
.getCurrentUser()));
161+
} else if (response.getError().getErrorCode() == ErrorCodes
162+
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
163+
setStatus("Merge conflict: user already exists.");
164+
mBinding.resolveMerge.setEnabled(true);
165+
mPendingCredential = response.getCredentialForLinking();
166+
} else {
167+
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
168+
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
169+
}
170+
171+
updateUI();
176172
}
177173

178174
private void updateUI() {
@@ -220,4 +216,9 @@ private String getUserIdentifier(FirebaseUser user) {
220216
return "unknown";
221217
}
222218
}
219+
220+
@Override
221+
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
222+
handleSignInResult(result.getResultCode(), result.getIdpResponse());
223+
}
223224
}

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

+20-17
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.firebase.ui.auth.AuthUI.IdpConfig;
2929
import com.firebase.ui.auth.ErrorCodes;
3030
import com.firebase.ui.auth.IdpResponse;
31+
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
32+
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
3133
import com.firebase.ui.auth.util.ExtraConstants;
3234
import com.firebase.uidemo.R;
3335
import com.firebase.uidemo.databinding.AuthUiLayoutBinding;
@@ -43,6 +45,8 @@
4345
import java.util.ArrayList;
4446
import java.util.List;
4547

48+
import androidx.activity.result.ActivityResultCallback;
49+
import androidx.activity.result.ActivityResultLauncher;
4650
import androidx.annotation.DrawableRes;
4751
import androidx.annotation.NonNull;
4852
import androidx.annotation.Nullable;
@@ -51,7 +55,8 @@
5155
import androidx.appcompat.app.AppCompatActivity;
5256
import androidx.appcompat.app.AppCompatDelegate;
5357

54-
public class AuthUiActivity extends AppCompatActivity {
58+
public class AuthUiActivity extends AppCompatActivity
59+
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
5560
private static final String TAG = "AuthUiActivity";
5661

5762
private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
@@ -65,6 +70,9 @@ public class AuthUiActivity extends AppCompatActivity {
6570

6671
private AuthUiLayoutBinding mBinding;
6772

73+
private final ActivityResultLauncher<Intent> signIn =
74+
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);
75+
6876
@NonNull
6977
public static Intent createIntent(@NonNull Context context) {
7078
return new Intent(context, AuthUiActivity.class);
@@ -209,11 +217,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {
209217
}
210218

211219
public void signIn() {
212-
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
220+
signIn.launch(getSignInIntent(/*link=*/null));
213221
}
214222

215223
public void signInWithEmailLink(@Nullable String link) {
216-
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
224+
signIn.launch(getSignInIntent(link));
217225
}
218226

219227
@NonNull
@@ -226,8 +234,7 @@ public AuthUI getAuthUI() {
226234
return authUI;
227235
}
228236

229-
@NonNull
230-
public Intent buildSignInIntent(@Nullable String link) {
237+
private Intent getSignInIntent(@Nullable String link) {
231238
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
232239
.setTheme(getSelectedTheme())
233240
.setLogo(getSelectedLogo())
@@ -262,7 +269,6 @@ public Intent buildSignInIntent(@Nullable String link) {
262269
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
263270
builder.enableAnonymousUsersAutoUpgrade();
264271
}
265-
266272
return builder.build();
267273
}
268274

@@ -280,14 +286,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
280286
});
281287
}
282288

283-
@Override
284-
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
285-
super.onActivityResult(requestCode, resultCode, data);
286-
if (requestCode == RC_SIGN_IN) {
287-
handleSignInResponse(resultCode, data);
288-
}
289-
}
290-
291289
@Override
292290
protected void onResume() {
293291
super.onResume();
@@ -298,9 +296,7 @@ protected void onResume() {
298296
}
299297
}
300298

301-
private void handleSignInResponse(int resultCode, @Nullable Intent data) {
302-
IdpResponse response = IdpResponse.fromResultIntent(data);
303-
299+
private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
304300
// Successfully signed in
305301
if (resultCode == RESULT_OK) {
306302
startSignedInActivity(response);
@@ -502,4 +498,11 @@ private List<String> getFacebookPermissions() {
502498
private void showSnackbar(@StringRes int errorMessageRes) {
503499
Snackbar.make(mBinding.getRoot(), errorMessageRes, Snackbar.LENGTH_LONG).show();
504500
}
501+
502+
@Override
503+
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
504+
// Successfully signed in
505+
IdpResponse response = result.getIdpResponse();
506+
handleSignInResponse(result.getResultCode(), response);
507+
}
505508
}

auth/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Gradle, add the dependency:
6666
```groovy
6767
dependencies {
6868
// ...
69-
implementation 'com.firebaseui:firebase-ui-auth:7.1.1'
69+
implementation 'com.firebaseui:firebase-ui-auth:7.2.0'
7070
7171
// Required only if Facebook login support is required
7272
// Find the latest Facebook SDK releases here: https://github.com/facebook/facebook-android-sdk/blob/master/CHANGELOG.md

auth/build.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ android {
6161
}
6262

6363
dependencies {
64+
implementation(Config.Libs.Androidx.activity)
65+
// The new activity result APIs force us to include Fragment 1.3.0
66+
// See https://issuetracker.google.com/issues/152554847
67+
implementation(Config.Libs.Androidx.fragment)
6468
implementation(Config.Libs.Androidx.design)
6569
implementation(Config.Libs.Androidx.customTabs)
6670
implementation(Config.Libs.Androidx.constraint)

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

+27-2
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,9 @@ private String getDefaultIso() {
10661066
public static final class GoogleBuilder extends Builder {
10671067
public GoogleBuilder() {
10681068
super(GoogleAuthProvider.PROVIDER_ID);
1069+
}
1070+
1071+
private void validateWebClientId() {
10691072
Preconditions.checkConfigured(getApplicationContext(),
10701073
"Check your google-services plugin configuration, the" +
10711074
" default_web_client_id string wasn't populated.",
@@ -1103,8 +1106,29 @@ public GoogleBuilder setSignInOptions(@NonNull GoogleSignInOptions options) {
11031106
ExtraConstants.GOOGLE_SIGN_IN_OPTIONS);
11041107

11051108
GoogleSignInOptions.Builder builder = new GoogleSignInOptions.Builder(options);
1106-
builder.requestEmail().requestIdToken(getApplicationContext()
1107-
.getString(R.string.default_web_client_id));
1109+
1110+
String clientId = options.getServerClientId();
1111+
if (clientId == null) {
1112+
validateWebClientId();
1113+
clientId = getApplicationContext().getString(R.string.default_web_client_id);
1114+
}
1115+
1116+
// Warn the user that they are _probably_ doing the wrong thing if they
1117+
// have not called requestEmail (see issue #1899 and #1621)
1118+
boolean hasEmailScope = false;
1119+
for (Scope s : options.getScopes()) {
1120+
if ("email".equals(s.getScopeUri())) {
1121+
hasEmailScope = true;
1122+
break;
1123+
}
1124+
}
1125+
if (!hasEmailScope) {
1126+
Log.w(TAG, "The GoogleSignInOptions passed to setSignInOptions does not " +
1127+
"request the 'email' scope. In most cases this is a mistake! " +
1128+
"Call requestEmail() on the GoogleSignInOptions object.");
1129+
}
1130+
1131+
builder.requestIdToken(clientId);
11081132
getParams().putParcelable(
11091133
ExtraConstants.GOOGLE_SIGN_IN_OPTIONS, builder.build());
11101134

@@ -1115,6 +1139,7 @@ public GoogleBuilder setSignInOptions(@NonNull GoogleSignInOptions options) {
11151139
@Override
11161140
public IdpConfig build() {
11171141
if (!getParams().containsKey(ExtraConstants.GOOGLE_SIGN_IN_OPTIONS)) {
1142+
validateWebClientId();
11181143
setScopes(Collections.<String>emptyList());
11191144
}
11201145

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.firebase.ui.auth;
2+
3+
import android.content.Context;
4+
import android.content.Intent;
5+
6+
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
7+
8+
import androidx.activity.result.contract.ActivityResultContract;
9+
import androidx.annotation.NonNull;
10+
import androidx.annotation.Nullable;
11+
12+
/**
13+
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
14+
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
15+
* result. The given input intent <b>must</b> be created using a
16+
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
17+
* launch of the authentication flow.
18+
*/
19+
public class FirebaseAuthUIActivityResultContract extends
20+
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {
21+
22+
@NonNull
23+
@Override
24+
public Intent createIntent(@NonNull Context context, Intent input) {
25+
return input;
26+
}
27+
28+
@Override
29+
@NonNull
30+
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
31+
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
32+
}
33+
34+
}

0 commit comments

Comments
 (0)