Skip to content

Commit 268b80a

Browse files
committed
Added linking for federated sign in with existing email. Dealt with email mismatch and added code review changes.
1 parent be0d864 commit 268b80a

16 files changed

+258
-159
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ public void startAuthUI() {
8181
List<AuthUI.IdpConfig> providers = Arrays.asList(
8282
new AuthUI.IdpConfig.EmailBuilder().build(),
8383
new AuthUI.IdpConfig.PhoneBuilder().build(),
84-
new AuthUI.IdpConfig.GoogleBuilder().build());
84+
new AuthUI.IdpConfig.GoogleBuilder().build(),
85+
new AuthUI.IdpConfig.FacebookBuilder().build(),
86+
new AuthUI.IdpConfig.TwitterBuilder().build());
8587

8688
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
8789
.setAvailableProviders(providers)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import com.google.android.gms.common.Scopes;
4242
import com.google.android.gms.tasks.OnCompleteListener;
4343
import com.google.android.gms.tasks.Task;
44-
import com.google.firebase.auth.AuthCredential;
4544
import com.google.firebase.auth.AuthResult;
4645
import com.google.firebase.auth.FirebaseAuth;
4746

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public final class ErrorCodes {
2020
PLAY_SERVICES_UPDATE_CANCELLED,
2121
DEVELOPER_ERROR,
2222
PROVIDER_ERROR,
23-
ANONYMOUS_UPGRADE_MERGE_CONFLICT
23+
ANONYMOUS_UPGRADE_MERGE_CONFLICT,
24+
EMAIL_MISMATCH_ERROR
2425
})
2526
@Retention(RetentionPolicy.SOURCE)
2627
public @interface Code {}
@@ -55,6 +56,12 @@ public final class ErrorCodes {
5556
*/
5657
public static final int ANONYMOUS_UPGRADE_MERGE_CONFLICT = 5;
5758

59+
/**
60+
* Signing in with a different email in the WelcomeBackIdp flow.
61+
*/
62+
public static final int EMAIL_MISMATCH_ERROR = 6;
63+
64+
5865
private ErrorCodes() {
5966
throw new AssertionError("No instance for you!");
6067
}
@@ -74,7 +81,10 @@ public static String toFriendlyMessage(@Code int code) {
7481
case PROVIDER_ERROR:
7582
return "Provider error";
7683
case ANONYMOUS_UPGRADE_MERGE_CONFLICT:
77-
return "Merge conflict";
84+
return "User account merge conflict";
85+
case EMAIL_MISMATCH_ERROR:
86+
return "You are are attempting to sign in a different email than previously " +
87+
"provided";
7888
default:
7989
throw new IllegalArgumentException("Unknown code: " + code);
8090
}
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
package com.firebase.ui.auth;
22

33
import android.support.annotation.NonNull;
4-
import android.support.annotation.Nullable;
54
import android.support.annotation.RestrictTo;
65

7-
import com.firebase.ui.auth.IdpResponse;
8-
import com.google.firebase.auth.AuthCredential;
9-
import com.google.firebase.auth.FirebaseAuthUserCollisionException;
10-
116
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
127
public class FirebaseAuthAnonymousUpgradeException extends Exception {
138

14-
private IdpResponse response;
9+
private IdpResponse mResponse;
1510

1611
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
1712
public FirebaseAuthAnonymousUpgradeException(@ErrorCodes.Code int code,
1813
@NonNull IdpResponse response) {
1914
super(ErrorCodes.toFriendlyMessage(code));
20-
this.response = response;
15+
mResponse = response;
2116
}
2217

2318
public IdpResponse getResponse() {
24-
return response;
19+
return mResponse;
2520
}
2621
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ public void writeToParcel(Parcel dest, int flags) {
232232
dest.writeString(mToken);
233233
dest.writeString(mSecret);
234234
dest.writeInt(mIsNewUser ? 1 : 0);
235+
235236
ObjectOutputStream oos = null;
236237
try {
237238
oos = new ObjectOutputStream(new ByteArrayOutputStream());
@@ -254,6 +255,7 @@ public void writeToParcel(Parcel dest, int flags) {
254255
} catch (IOException ignored) {}
255256
}
256257
}
258+
257259
dest.writeParcelable(mPendingCredential, 0);
258260
}
259261

@@ -268,7 +270,9 @@ public boolean equals(Object o) {
268270
&& (mToken == null ? response.mToken == null : mToken.equals(response.mToken))
269271
&& (mSecret == null ? response.mSecret == null : mSecret.equals(response.mSecret))
270272
&& (mIsNewUser == response.mIsNewUser)
271-
&& (mException == null ? response.mException == null : mException.equals(response.mException));
273+
&& (mException == null ? response.mException == null : mException.equals(response.mException))
274+
&& (mPendingCredential == null ? response.mPendingCredential == null :
275+
mPendingCredential.equals(response.mPendingCredential));
272276
}
273277

274278
@Override

auth/src/main/java/com/firebase/ui/auth/data/model/Resource.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ public T getValue() {
6565
return mValue;
6666
}
6767

68-
public boolean hasValue() {
69-
return mValue != null;
70-
}
71-
7268
public boolean isUsed() {
7369
return mIsUsed;
7470
}

auth/src/main/java/com/firebase/ui/auth/data/remote/EmailSignInHandler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ public void startSignIn(@NonNull HelperActivityBase activity) {
3232
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
3333
if (resultCode == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
3434
// The activity deals with this case. This conflict is handled by the developer.
35-
}
36-
if (requestCode == RequestCodes.EMAIL_FLOW) {
35+
} else if (requestCode == RequestCodes.EMAIL_FLOW) {
3736
IdpResponse response = IdpResponse.fromResultIntent(data);
3837
if (response == null) {
3938
setResult(Resource.<IdpResponse>forFailure(new UserCancellationException()));

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,8 @@ protected static Intent createBaseIntent(
4040
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
4141
super.onActivityResult(requestCode, resultCode, data);
4242
// Forward the results of Smart Lock saving
43-
if (requestCode == RequestCodes.CRED_SAVE_FLOW) {
44-
finish(resultCode, data);
45-
}
46-
47-
if (resultCode == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
43+
if (requestCode == RequestCodes.CRED_SAVE_FLOW
44+
|| resultCode == ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
4845
finish(resultCode, data);
4946
}
5047
}

auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailFragment.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ public void run() {
215215
@Override
216216
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
217217
super.onActivityCreated(savedInstanceState);
218-
requireActivity().setTitle(R.string.fui_title_register_email);
219-
FragmentActivity activity = getActivity();
218+
FragmentActivity activity = requireActivity();
219+
activity.setTitle(R.string.fui_title_register_email);
220220
if (!(activity instanceof AnonymousUpgradeListener)) {
221221
throw new IllegalStateException("Activity must implement CheckEmailListener");
222222
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
import com.firebase.ui.auth.AuthUI;
3636
import com.firebase.ui.auth.AuthUI.IdpConfig;
37+
import com.firebase.ui.auth.FirebaseAuthAnonymousUpgradeException;
38+
import com.firebase.ui.auth.FirebaseUiException;
3739
import com.firebase.ui.auth.IdpResponse;
3840
import com.firebase.ui.auth.R;
3941
import com.firebase.ui.auth.data.model.FlowParameters;
@@ -109,9 +111,13 @@ protected void onSuccess(@NonNull IdpResponse response) {
109111

110112
@Override
111113
protected void onFailure(@NonNull Exception e) {
112-
if (!(e instanceof UserCancellationException)) {
114+
if (e instanceof FirebaseAuthAnonymousUpgradeException) {
115+
onMergeFailure(((FirebaseAuthAnonymousUpgradeException) e).getResponse());
116+
} else if ( (!(e instanceof UserCancellationException))) {
117+
String text = e instanceof FirebaseUiException ? e.getMessage() :
118+
getString(R.string.fui_error_unknown);
113119
Toast.makeText(AuthMethodPickerActivity.this,
114-
R.string.fui_error_unknown,
120+
text,
115121
Toast.LENGTH_SHORT).show();
116122
}
117123
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
8989
supplier.get(LinkingSocialProviderResponseHandler.class);
9090
handler.init(getFlowParams());
9191
if (requestedUserResponse != null) {
92-
handler.setRequestedSignInCredential(
93-
ProviderUtils.getAuthCredential(requestedUserResponse));
92+
handler.setRequestedSignInCredentialForEmail(
93+
ProviderUtils.getAuthCredential(requestedUserResponse),
94+
existingUser.getEmail());
9495
}
9596

9697
String providerId = existingUser.getProviderId();

auth/src/main/java/com/firebase/ui/auth/util/data/AuthOperationManager.java

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
package com.firebase.ui.auth.util.data;
22

3-
import android.content.Context;
4-
import android.content.Intent;
53
import android.support.annotation.NonNull;
64
import android.support.annotation.RestrictTo;
75

8-
import com.firebase.ui.auth.IdpResponse;
96
import com.firebase.ui.auth.data.model.FlowParameters;
10-
import com.firebase.ui.auth.util.ExtraConstants;
7+
import com.google.android.gms.tasks.Continuation;
118
import com.google.android.gms.tasks.Task;
129
import com.google.firebase.FirebaseApp;
1310
import com.google.firebase.auth.AuthCredential;
@@ -23,7 +20,7 @@ public class AuthOperationManager {
2320

2421
private static String firebaseAppName = "FUIScratchApp";
2522

26-
public static synchronized FirebaseApp getScratchApp(FirebaseApp defaultApp) {
23+
private static synchronized FirebaseApp getScratchApp(FirebaseApp defaultApp) {
2724
try {
2825
return FirebaseApp.getInstance(firebaseAppName);
2926
} catch (IllegalStateException e) {
@@ -32,6 +29,13 @@ public static synchronized FirebaseApp getScratchApp(FirebaseApp defaultApp) {
3229
}
3330
}
3431

32+
public static FirebaseAuth getScratchAuth(FlowParameters flowParameters) {
33+
// Use a different FirebaseApp so that the anonymous user state is not lost in our
34+
// original FirebaseAuth instance.
35+
FirebaseApp app = FirebaseApp.getInstance(flowParameters.appName);
36+
return FirebaseAuth.getInstance(getScratchApp(app));
37+
}
38+
3539
public static Task<AuthResult> createOrLinkUserWithEmailAndPassword(@NonNull FirebaseAuth auth,
3640
@NonNull FlowParameters flowParameters,
3741
@NonNull String email,
@@ -62,11 +66,26 @@ public static boolean canUpgradeAnonymous(FirebaseAuth auth, FlowParameters flow
6266
@NonNull
6367
public static Task<AuthResult> validateCredential(AuthCredential credential,
6468
FlowParameters flowParameters) {
65-
// Use a different FirebaseApp so that the anonymous user state is not lost in our
66-
// original FirebaseAuth instance.
67-
FirebaseApp app = FirebaseApp.getInstance(flowParameters.appName);
68-
FirebaseAuth scratchAuth = FirebaseAuth
69-
.getInstance(app);
70-
return scratchAuth.signInWithCredential(credential);
69+
return getScratchAuth(flowParameters).signInWithCredential(credential);
70+
}
71+
72+
public static Task<AuthResult> safeLink(final AuthCredential credential,
73+
final AuthCredential credentialToLink,
74+
final FlowParameters flowParameters) {
75+
76+
77+
return getScratchAuth(flowParameters)
78+
.signInWithCredential(credential)
79+
.continueWithTask(new Continuation<AuthResult, Task<AuthResult>>() {
80+
@Override
81+
public Task<AuthResult> then(@NonNull Task<AuthResult> task) throws Exception {
82+
if (task.isSuccessful()) {
83+
return AuthOperationManager.getScratchAuth(flowParameters)
84+
.getCurrentUser()
85+
.linkWithCredential(credentialToLink);
86+
}
87+
return task;
88+
}
89+
});
7190
}
7291
}

auth/src/main/java/com/firebase/ui/auth/util/data/ProviderUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,9 @@ public String then(@NonNull Task<String> task) {
170170
}
171171
});
172172
}
173+
174+
public static String getTopProvider(@NonNull List<String> providers) {
175+
return providers == null || providers.isEmpty() ? null :
176+
providers.get(providers.size() - 1);
177+
}
173178
}

0 commit comments

Comments
 (0)