-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Rewrite phone auth with new architecture and finalize progress revamp #1253
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
Rewrite phone auth with new architecture and finalize progress revamp #1253
Conversation
Signed-off-by: Alex Saveau <[email protected]>
|
Not gonna look at this yet but +604 -1406 !!!! |
β¦rewrite # Conflicts: # auth/src/main/java/com/firebase/ui/auth/data/remote/TwitterSignInHandler.java # auth/src/main/java/com/firebase/ui/auth/ui/phone/VerifyPhoneNumberFragment.java # auth/src/test/java/com/firebase/ui/auth/ui/phone/PhoneActivityTest.java
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
|
@samtstern Alrighty, this one is ready for review! Gonna take a look a your PR next. Some notes about this PR:
|
|
@SUPERCILEX excited to review this one! But I've come down with a really strong case of I/O fever, so if I get to this at all this week it will be on Friday. Sorry and appreciate the effort / patience! |
| <string name="fui_error_quota_exceeded">OcurriΓ³ un problema durante la verificaciΓ³n de tu nΓΊmero de telΓ©fono</string> | ||
| <string name="fui_error_session_expired">Este cΓ³digo ya no es vΓ‘lido</string> | ||
| <string name="fui_sign_in_with_phone_number">Acceder con el nΓΊmero de telΓ©fono</string> | ||
| <string name="fui_done">Listo</string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is definitely a highly annoying request, but could we split out the string removals into another PR? That way this one doesn't have 177 files changed and thousands of lines. I don't want an important behavioral change to get lost among all of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not at all, I thought you might ask so I removed all the strings in one easily rebasable commit. π
samtstern
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some brief comments.
| break; | ||
| case PhoneAuthProvider.PROVIDER_ID: | ||
| Bundle args = new Bundle(); | ||
| args.putString(ExtraConstants.PHONE, email); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we rename the email arg to identifier or something? Seems strange to see put(PHONE, email)
| return mParams; | ||
| } | ||
|
|
||
| public AuthHelper getAuthHelper() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the helper activity doesn't even have a helper! Love seeing this class die haha.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, that was the first class to die when I started the refactorβit killed me when I had to add it back for the staged PRs. π
| nationalNumber = params.getString(ExtraConstants.NATIONAL_NUMBER); | ||
| } | ||
|
|
||
| if (!TextUtils.isEmpty(countryIso) && !TextUtils.isEmpty(nationalNumber)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: This block is pretty much the heart of the decision making here so I think a comment or two would be good, especially for the final elseif block.
| mPhoneEditText.setSelection(number.getPhoneNumber().length()); | ||
| } | ||
| if (PhoneNumber.isCountryValid(number)) { | ||
| setCountryCode(number); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If isCountryValid is true but isValid is false then it looks like we'll call onNext() with a situation that will cause getPseudoValidPhoneNumber() to return null and then put an error on screen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, you're right.
| mPhoneNumber = savedInstanceState.getString(KEY_VERIFICATION_PHONE); | ||
| final PhoneProviderResponseHandler handler = | ||
| ViewModelProviders.of(this).get(PhoneProviderResponseHandler.class); | ||
| handler.init(getFlowParams()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: name this something more specific than handler? When it's used inside of verificationHandler it gets a bit confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed verificationHandler to phoneVerifier.
| protected void onSuccess(@NonNull PhoneAuthCredential credential) { | ||
| handler.startSignIn(credential, new IdpResponse.Builder( | ||
| new User.Builder(PhoneAuthProvider.PROVIDER_ID, null) | ||
| .setPhoneNumber(getPhoneNumber()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok looking at the two methods where we do fragment detection, getErrorView() and getPhoneNumber(), that's where we both agree we could improve.
Here I see that we use getPhoneNumber() in the verification handler to kick off the other handler.
What's the original reason why this flow benefits from being a multi-Fragment activity rather than a series of activities? Would that help cut down on the patterns we don't like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You actually just gave me a different idea here: I made the phone number pass through the verification view modelβnot sure why I didn't think of that before. π€¦ββοΈ It still doesn't address the error view thing though, but that's not as bad as the phone number bit IMO.
As for activities, I'm not sure how they would be solving our problem... they would make it harder to talk between them since we'd be relying on a bunch of bundles. Whad'ya think of bfb3b22? It's certainly an improvement over the current PhoneActivity! π
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks better to me!
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
| } | ||
|
|
||
| private void start(PhoneNumber number) { | ||
| if (PhoneNumber.isValid(number)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: nornmally I think this pattern is clearer:
if (bad condition) {
// ...
return;
}
// Good condition....Less indentation and survives future editing better.
|
|
||
| import com.firebase.ui.auth.R; | ||
|
|
||
| public final class CompletableProgressDialog extends DialogFragment { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am all for killing this dialog, but we should preserve the UX that it was meant to provide. This special "checkmark progress dialog" thing came from UX studies that the former Digits team did.
In the situation where the phone number is auto-verified or the SMS is auto-retrieved, it can be opaque to the user why they were signed in without any action.
So we need to handle each of those two cases in the UI specifically.
| } | ||
|
|
||
| private void onCodeSent() { | ||
| completeLoadingDialog(getString(R.string.fui_code_sent)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is part of the same comment from above, making sure that even when things happen really quickly the user has a chance to notice each step of phone auth.
| new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { | ||
| @Override | ||
| public void onVerificationCompleted(@NonNull PhoneAuthCredential credential) { | ||
| setResult(Resource.forSuccess(Pair.create(number, credential))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the case where retrieval happened without any user interaction. Any ideas for how we can send a special signal to the UI and what it should look like?
| * CheckPhoneNumberFragment} and {@link SubmitConfirmationCodeFragment} | ||
| */ | ||
| @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) | ||
| public class PhoneActivity extends AppCompatBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this text-free dialog that flickers into and out of existence at the start of the flow?
https://drive.google.com/file/d/1DifkJhYY8iPVGW2AWgTnc0muPyFPWsPf/view
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That one isn't my fault, it's the Smart Lock dialog. π€·ββοΈ Not much we can do there.
| mSubmitConfirmationButton = view.findViewById(R.id.submit_confirmation_code); | ||
|
|
||
| getActivity().setTitle(getString(R.string.fui_verify_your_phone_title)); | ||
| mCountdown.run(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be mHandler.postRunnable(mCountDown()) instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
|
@SUPERCILEX do you think you can address the UX concerns and all other remaining issues in time for Also if there are any translations needed for this and you're shooting for |
|
@samtstern yeah, probably not going to get this done in time so 4.0.1 it is. (Unless I beat the tos translations and you have time to reviewβagain, not likely. π) |
# Conflicts: # auth/src/main/java/com/firebase/ui/auth/ui/HelperActivityBase.java # auth/src/main/java/com/firebase/ui/auth/ui/idp/AuthMethodPickerActivity.java # auth/src/main/java/com/firebase/ui/auth/ui/phone/CompletableProgressDialog.java # auth/src/main/java/com/firebase/ui/auth/ui/phone/PhoneActivity.java # auth/src/main/java/com/firebase/ui/auth/ui/phone/SubmitConfirmationCodeFragment.java # auth/src/main/java/com/firebase/ui/auth/ui/phone/VerifyPhoneNumberFragment.java # auth/src/main/java/com/firebase/ui/auth/util/ui/PreambleHandler.java # auth/src/main/res/layout/fui_phone_progress_dialog.xml
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
| protected void onSuccess(@NonNull PhoneVerification verification) { | ||
| if (verification.isAutoVerified()) { | ||
| Toast.makeText( | ||
| PhoneActivity.this, R.string.fui_verified, Toast.LENGTH_LONG).show(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this address your auto verified concerns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a Snackbar? Or are we using Toast since it will last across the UI transition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh also I just went through and tried this, I think we should extend the fui_verified message to be something like "Phone number automatically verified"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm using a Toast since the UI will disappear too fast. And good point about the string, I'll rename it to fui_auto_verified too to minimize translation confusion.
Signed-off-by: Alex Saveau <[email protected]>
samtstern
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks mostly good!
Btw not sure if you saw this but it's now pretty easy to test all the different branches of this flow:
https://firebase.google.com/docs/auth/android/phone-auth#integration-testing
| public void showProgress(@StringRes int message) { | ||
| getDialogHolder().showLoadingDialog(message); | ||
| throw new UnsupportedOperationException( | ||
| "Either a fragment or activity must handle progress updates."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just make these two methods abstract then if we want to force the subclass to implement them?
I think what you're trying to do is not allow events to bubble up from fragments but maybe then we should remove the default behavior from the fragment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, I thought we still had some fragments that forwarded progress updates to the activity, but I guess the was in the ProgressDialog world. Everything is abstract now. π
| countryIso, | ||
| String.valueOf(PhoneNumberUtils.getCountryCode(countryIso)))); | ||
| } else if (getFlowParams().enableHints) { | ||
| FlowUtils.unhandled(this, new PendingIntentRequiredException( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a strange patter: we're faking a PendingIntentRequiredException just to launch the hint picker. Should we instead bubble up some event that will allow this to be fired from the ViewModel as normal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I'm even using mHandler.getApplication() for the context so I must have forgotten this bit sometime while refactoring. π
| protected void onSuccess(@NonNull PhoneVerification verification) { | ||
| if (verification.isAutoVerified()) { | ||
| Toast.makeText( | ||
| PhoneActivity.this, R.string.fui_verified, Toast.LENGTH_LONG).show(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about a Snackbar? Or are we using Toast since it will last across the UI transition?
| @Override | ||
| protected void onFailure(@NonNull Exception e) { | ||
| if (e instanceof PhoneNumberVerificationRequiredException) { | ||
| // Ignore if resending verification code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add some more explanation for how this comment relates to the code below?
| } | ||
| @Override | ||
| public void showProgress(int message) { | ||
| FragmentBase fragment = (CheckPhoneNumberFragment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we DRY up the first few lines from showProgress and hideProgress into some getActiveFragment method or something?
Signed-off-by: Alex Saveau <[email protected]>
|
@SUPERCILEX nice! This looks good to me once the conflicts are gone. I think for |
β¦rewrite # Conflicts: # auth/src/main/java/com/firebase/ui/auth/util/ui/PreambleHandler.java
|
@samtstern SGTM, though I had already merged from 4.1 dev. Do you want me to try and rebase those changes out to target 4.0.1? |
|
Oh whoops. That's my bad. Don't worry about it this can be in 4.1
β¦On Wed, May 30, 2018, 5:29 PM Alex Saveau ***@***.***> wrote:
@samtstern <https://github.com/samtstern> SGTM, though I had already
merged from 4.1 dev. Do you want me to try and rebase those changes out to
target 4.0.1?
β
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1253 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AIEw6u1MY8IKGtY17wKh3pgfGqjw21klks5t3zmCgaJpZM4TSo1m>
.
|
|
@SUPERCILEX boom! Your second big kahuna is now complete! |
This is it! Half a year later and we're almost done! ππΎπ