Skip to content

Request Twitter email #452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 15, 2016
4 changes: 2 additions & 2 deletions auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ Twitter app as reported by the [Twitter application manager](https://apps.twitte
</resources>
```

In addition, if you are using Smart Lock or require a user's email, you must enable the
"Request email addresses from users" permission in the "Permissions" tab of your app.
In addition, you must enable the "Request email addresses from users" permission
in the "Permissions" tab of your Twitter app.

## Using FirebaseUI for Authentication

Expand Down
2 changes: 1 addition & 1 deletion auth/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {
compile "com.google.android.gms:play-services-auth:$firebase_version"

compile 'com.facebook.android:facebook-android-sdk:4.18.0'
compile("com.twitter.sdk.android:twitter:2.2.0@aar") { transitive = true }
compile("com.twitter.sdk.android:twitter:2.3.0@aar") { transitive = true }

// The following libraries are needed to prevent incompatibilities with the facebook
// library when updating com.android.support libraries:
Expand Down
47 changes: 22 additions & 25 deletions auth/src/main/java/com/firebase/ui/auth/IdpResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.firebase.ui.auth.ui.ExtraConstants;
Expand All @@ -25,39 +26,37 @@
* A container that encapsulates the result of authenticating with an Identity Provider.
*/
public class IdpResponse implements Parcelable {

private final String mProviderId;
@Nullable
private final String mEmail;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this should be nullable: we always know the email address and provider id and since having it be nullable caused a crash, I made it @nonnull.

private final String mToken;
private final String mSecret;
private final int mErrorCode;

public IdpResponse(int errorCode) {
private IdpResponse(int errorCode) {
this(null, null, null, null, errorCode);
}

public IdpResponse(String providerId, String email) {
this(providerId, email, null, null);
public IdpResponse(@NonNull String providerId, @NonNull String email) {
this(providerId, email, null, null, ResultCodes.OK);
}

public IdpResponse(String providerId, @Nullable String email, @Nullable String token) {
this(providerId, email, token, null);
public IdpResponse(@NonNull String providerId, @NonNull String email, @NonNull String token) {
this(providerId, email, token, null, ResultCodes.OK);
}

public IdpResponse(
String providerId,
@Nullable String email,
@Nullable String token,
@Nullable String secret) {
@NonNull String providerId,
@NonNull String email,
@NonNull String token,
@NonNull String secret) {
this(providerId, email, token, secret, ResultCodes.OK);
}

public IdpResponse(
private IdpResponse(
String providerId,
@Nullable String email,
@Nullable String token,
@Nullable String secret,
String email,
String token,
String secret,
int errorCode) {
mProviderId = providerId;
mEmail = email;
Expand Down Expand Up @@ -87,11 +86,17 @@ public IdpResponse[] newArray(int size) {
/**
* Get the type of provider. e.g. {@link AuthUI#GOOGLE_PROVIDER}
*/
@Nullable
public String getProviderType() {
return mProviderId;
}

/**
* Get the email used to sign in.
*/
public String getEmail() {
return mEmail;
}

/**
* Get the token received as a result of logging in with the specified IDP
*/
Expand All @@ -108,14 +113,6 @@ public String getIdpSecret() {
return mSecret;
}

/**
* Get the email used to sign in.
*/
@Nullable
public String getEmail() {
return mEmail;
}

/**
* Get the error code for a failed sign in
*/
Expand Down Expand Up @@ -157,6 +154,6 @@ public static Intent getIntent(IdpResponse response) {
}

public static Intent getErrorCodeIntent(int errorCode) {
return new Intent().putExtra(ExtraConstants.EXTRA_IDP_RESPONSE, new IdpResponse(errorCode));
return getIntent(new IdpResponse(errorCode));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public void startLogin(Activity activity) {

@Override
public void setAuthenticationCallback(IdpCallback callback) {
this.mCallbackObject = callback;
mCallbackObject = callback;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.twitter.sdk.android.core.TwitterSession;
import com.twitter.sdk.android.core.identity.TwitterAuthClient;

import java.lang.ref.WeakReference;

import io.fabric.sdk.android.Fabric;

public class TwitterProvider extends Callback<TwitterSession> implements IdpProvider {
Expand Down Expand Up @@ -46,7 +48,7 @@ public String getProviderId() {

@Override
public void setAuthenticationCallback(IdpCallback callback) {
this.mCallbackObject = callback;
mCallbackObject = callback;
}

@Override
Expand All @@ -61,7 +63,7 @@ public void startLogin(Activity activity) {

@Override
public void success(Result<TwitterSession> result) {
mCallbackObject.onSuccess(createIdpResponse(result.data));
mTwitterAuthClient.requestEmail(result.data, new EmailCallback(result.data, mCallbackObject));
}

@Override
Expand All @@ -70,21 +72,47 @@ public void failure(TwitterException exception) {
mCallbackObject.onFailure(new Bundle());
}

private IdpResponse createIdpResponse(TwitterSession twitterSession) {
return new IdpResponse(
TwitterAuthProvider.PROVIDER_ID,
null,
twitterSession.getAuthToken().token,
twitterSession.getAuthToken().secret);
}
private static class EmailCallback extends Callback<String> {
private TwitterSession mTwitterSession;
private WeakReference<IdpCallback> mCallbackObject;

public EmailCallback(TwitterSession session, IdpCallback callbackObject) {
mTwitterSession = session;
mCallbackObject = new WeakReference<>(callbackObject);
}

@Override
public void success(Result<String> emailResult) {
onSuccess(createIdpResponse(emailResult.data));
}

@Override
public void failure(TwitterException exception) {
Log.e(TAG, "Failure retrieving Twitter email. " + exception.getMessage());
// If retrieving the email fails, we should still be able to sign in, but Smart Lock
// and account linking won't work.
onSuccess(createIdpResponse(null));
}

private void onSuccess(IdpResponse response) {
if (mCallbackObject != null) {
mCallbackObject.get().onSuccess(response);
}
}

private IdpResponse createIdpResponse(String email) {
return new IdpResponse(
TwitterAuthProvider.PROVIDER_ID,
email,
mTwitterSession.getAuthToken().token,
mTwitterSession.getAuthToken().secret);
}
}

public static AuthCredential createAuthCredential(IdpResponse response) {
if (!response.getProviderType().equalsIgnoreCase(TwitterAuthProvider.PROVIDER_ID)){
if (!response.getProviderType().equalsIgnoreCase(TwitterAuthProvider.PROVIDER_ID)) {
return null;
}
return TwitterAuthProvider.getCredential(
response.getIdpToken(),
response.getIdpSecret());
return TwitterAuthProvider.getCredential(response.getIdpToken(), response.getIdpSecret());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,7 @@ protected void onDestroy() {
}
}

public static Intent createIntent(
Context context,
FlowParameters flowParams) {
public static Intent createIntent(Context context, FlowParameters flowParams) {
return BaseHelper.createBaseIntent(context, AuthMethodPickerActivity.class, flowParams);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,27 @@ public void onComplete(@NonNull Task<AuthResult> task) {
} else {
if (task.getException() instanceof FirebaseAuthUserCollisionException) {
final String email = mResponse.getEmail();
mHelper.getFirebaseAuth()
.fetchProvidersForEmail(email)
.addOnFailureListener(new TaskFailureLogger(
TAG, "Error fetching providers for email"))
.addOnSuccessListener(new StartWelcomeBackFlow(email))
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// TODO: What to do when signing in with Credential fails
// and we can't continue to Welcome back flow without
// knowing providers?
}
});
if (email != null) {
mHelper.getFirebaseAuth()
.fetchProvidersForEmail(email)
.addOnFailureListener(new TaskFailureLogger(
TAG, "Error fetching providers for email"))
.addOnSuccessListener(new StartWelcomeBackFlow(email))
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// TODO: What to do when signing in with Credential fails
// and we can't continue to Welcome back flow without
// knowing providers?
}
});
return;
}
} else {
mHelper.dismissDialog();
Log.e(TAG, "Unexpected exception when signing in with credential",
task.getException());
}
mHelper.dismissDialog();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import com.google.firebase.auth.FirebaseUser;

public class FakeAuthResult implements AuthResult {
FirebaseUser mFirebaseUser;
private FirebaseUser mFirebaseUser;

public FakeAuthResult(FirebaseUser firebaseUser) {
mFirebaseUser = firebaseUser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import java.util.List;

public class FakeProviderQueryResult implements ProviderQueryResult {
List<String> mProviders;
private List<String> mProviders;

public FakeProviderQueryResult(List<String> providers) {
mProviders = providers;
Expand Down

This file was deleted.

Loading