Skip to content

Default phone #906

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 6 commits into from
Sep 14, 2017
Merged

Default phone #906

merged 6 commits into from
Sep 14, 2017

Conversation

yramanchuk
Copy link
Contributor

Implement phone Auth flow Phone number configuration parameter.
Related issue #887

@SUPERCILEX
Copy link
Collaborator

@yramanchuk I believe the result of that issue was that FirebaseUI isn't going to support this kind of flow. Could you explain why you already have a phone number? The user should be giving that to FirebaseUI in the auth flow, not to you directly. Hope this clears things up! 😄

@ashwinraghav
Copy link
Contributor

@yramanchuk I think the issue that is linked to may not be completely comparable.

@SUPERCILEX The problem we are addressing is rooted in the fact that Firebase UI currently does not support 2FA (Say Facebook + Phone Auth). To work around this, apps that wish to use phone as the second factor can use Facebook login on their own outside Firebase UI and then use Firebase UI for the second factor phone auth.
This change helps apps that "know" the second factor phone number given a Facebook account, particularly when a user is logging into their secondary device like a tablet. Hope that helps.

@yramanchuk
Copy link
Contributor Author

@ashwinraghav Thanks for the clarification.
@SUPERCILEX here's another example: application may have multi-dialog account creation flow and they have already requested user to enter his phone number, so they would like to show phone verification dialog with pre-filled phone number.

Here's related FirebaseUI-iOS issue: firebase/FirebaseUI-iOS#306
This request is required for the feature parity: firebase/FirebaseUI-iOS#334

@@ -114,7 +115,8 @@ private void populateIdpList(List<IdpConfig> providers) {
mProviders.add(new EmailProvider(this, getFlowParams()));
break;
case AuthUI.PHONE_VERIFICATION_PROVIDER:
mProviders.add(new PhoneProvider(this, getFlowParams()));
PhoneIdpConfig phoneIdpConfig = (PhoneIdpConfig) idpConfig;
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this break older clients, breaking backward compatibility?

@@ -378,6 +368,79 @@ public IdpConfig build() {
}
}

public static class PhoneIdpConfig extends IdpConfig {
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like introducing a config per for phone auth provider leaves me desiring symmetry for such a config in other providers.

Also, the type safety that this implementation gives is hard to enforce in a backward compatible way. This leads to unsafe typecasting like the one made in

PhoneIdpConfig phoneIdpConfig = (PhoneIdpConfig) idpConfig;

My suggestion would be to introduce a Bundle parameter into the existing IdpConfig that yields an API that would look like:

Bundle b = new Bundle();
b.putString(AuthUI.PHONE_VERIFICATION_PROVIDER.DEFAULT_PHONE_EXTRA, "+16478488383");

new AuthUI.IdpConfig.Builder(AuthUI.PHONE_PROVIDER).setParams(bundle).build()) and wire it into the providers from that point on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ashwinraghav Thhank's for the suggestion. I was thinking about extending existing IdpConfig but in that case were are adding changes to all configs (Google, Facebook) and they they don't need that parameter.

Anyway I think your solution is more elegant. I just want to propose to use List of Bundles instead of just Bundle:

AuthUI.IdpConfig.Builder(AuthUI.PHONE_PROVIDER).setParams(List).build())

In that case we can pass multiple params.
@ashwinraghav what do you think?

@samtstern samtstern changed the base branch from master to version-2.3.1-dev September 12, 2017 23:52
@samtstern
Copy link
Contributor

@yramanchuk FYI I changed the target branch to the current development branch, version-2.3.1-dev.

@samtstern
Copy link
Contributor

Note that the issue of IDP-specific configuration has been discussed here as well:
#806

Copy link
Contributor

@samtstern samtstern left a comment

Choose a reason for hiding this comment

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

Mostly good, a few remaining comments,

// Use the params Bundle to provide a default phone number that will populate the
// phone number field in PhoneVerificationActivity if the number is known in advance.
Bundle params = new Bundle();
params.putString(AuthUI.PHONE_VERIFICATION_DEFAULT_PHONE_EXTRA, "+13099126574");
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a minor point, but I think putting a random phone number into the sample will cause confusion. Many people will want to use this sample to test phone auth with their real number.

This type of example snippet belongs in the README.

Copy link
Contributor

Choose a reason for hiding this comment

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

Moved to README, let me know if you don't think it's in an appropriate location.

startActivityForResult(
PhoneVerificationActivity.createIntent(getContext(), flowParams, null),
PhoneVerificationActivity.createIntent(getContext(), flowParams, phone),
Copy link
Contributor

Choose a reason for hiding this comment

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

This createIntent call uses ExtraConstants.EXTRA_PHONE. We should unify the values between this and AuthUI.PHONE_VERIFICATION_DEFAULT_PHONE_EXTRA.

I'd suggest:

class AuthUI {
  // ...
  public static final String EXTRA_DEFAULT_PHONE = ExtraConstants.EXTRA_PHONE;
  // ...
}

Copy link
Contributor

Choose a reason for hiding this comment

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

That's reasonable, made your suggested change.

@@ -114,7 +115,8 @@ private void populateIdpList(List<IdpConfig> providers) {
mProviders.add(new EmailProvider(this, getFlowParams()));
break;
case AuthUI.PHONE_VERIFICATION_PROVIDER:
mProviders.add(new PhoneProvider(this, getFlowParams()));
PhoneIdpConfig phoneIdpConfig = (PhoneIdpConfig) idpConfig;
Copy link
Contributor

Choose a reason for hiding this comment

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

This class PhoneIdpConfig is used here but I don't see it defined in this PR anymore. I think changes to this file need to be revisited.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, gone now.

@samtstern
Copy link
Contributor

@SUPERCILEX the main reason for supporting this flow is feature parity with what Digits used to offer. We are telling all Digits developers to move to FirebaseUI and some of them noticed this missing feature.

You are right though, it was not a flow we originally intended to support. Ashwin and Yury have provided some examples where it can be very useful though.

Copy link
Collaborator

@SUPERCILEX SUPERCILEX left a comment

Choose a reason for hiding this comment

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

@yramanchuk @ashwinraghav @samtstern Thanks for all your explanations, I see why this is necessary now!

@yramanchuk I just have a few comments.

@@ -338,7 +338,8 @@ private int getSelectedLogo() {

if (mUsePhoneProvider.isChecked()) {
selectedProviders.add(
new IdpConfig.Builder(AuthUI.PHONE_VERIFICATION_PROVIDER).build());
new IdpConfig.Builder(AuthUI.PHONE_VERIFICATION_PROVIDER)
.build());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Might as well undo the changes in this file since they're leftovers from previous commits.

Copy link
Contributor

Choose a reason for hiding this comment

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

Reverted.

paramsValueBuilder.append(mParams.get(key).toString());
paramsValueBuilder.append(",");
}
paramsValueBuilder.append("}");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Doesn't Bundle already have a toString() with very similar behavior?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, just check the source and Bundle#toString() calls mMap.toString(). I'm assuming the formatting will be a little bit different, but the output should be effectively the same.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, did not realize that. Switched to the Bundle toString.

String phone = null;
for (AuthUI.IdpConfig idpConfig : mFlowParameters.providerInfo) {
if (idpConfig.getProviderId().equals(AuthUI.PHONE_VERIFICATION_PROVIDER)) {
phone = idpConfig.getParams().getString(EXTRA_DEFAULT_PHONE);
Copy link
Collaborator

Choose a reason for hiding this comment

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

To be consistent, we shouldn't statically import this and instead use AuthUI.EXTRA_DEFAULT_PHONE.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fixed

@@ -248,8 +248,12 @@ private void startAuthMethodChoice() {
break;
case PhoneAuthProvider.PROVIDER_ID:
// Go directly to phone flow
String phone = idpConfigs
.get(0)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This same logic is used above so we should probably extract a firstIdpConfig and replace firstProvider with the method call.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good point, done.

}

private IdpConfig(Parcel in) {
mProviderId = in.readString();
mScopes = Collections.unmodifiableList(in.createStringArrayList());
mParams = in.readBundle();
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be in.readBundle(getClass().getClassLoader()) to make the build pass. Since we're just passing in strings right now we don't actually need this, but it'll ensure we're future proof (and make lint happy).

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, just noticed the CONTRIBUTING.md file. Apologies - just beginning contribution to the library and obviously wasn't paying full attention. Made the change and build should be passing now. Thanks for the review by the way!

@@ -332,12 +350,14 @@ public String toString() {
return "IdpConfig{" +
"mProviderId='" + mProviderId + '\'' +
", mScopes=" + mScopes +
", mParams=" + mParams.toString() +
Copy link
Collaborator

Choose a reason for hiding this comment

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

One last nit! 😄 We don't need the toString() call, mParams alone is just fine.

Copy link
Contributor

Choose a reason for hiding this comment

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

Removed.

Copy link
Collaborator

@SUPERCILEX SUPERCILEX left a comment

Choose a reason for hiding this comment

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

@yramanchuk Sweet, LGTM! 😄

Copy link
Contributor

@samtstern samtstern left a comment

Choose a reason for hiding this comment

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

LGTM

@samtstern
Copy link
Contributor

I will merge this once Travis is happy.

@samtstern samtstern merged commit e4ece3a into version-2.3.1-dev Sep 14, 2017
@samtstern samtstern added this to the 2.3.1 milestone Sep 14, 2017
@samtstern samtstern deleted the default_phone branch September 29, 2017 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants