【问题标题】:Firebase phone authentications flowFirebase 电话身份验证流程
【发布时间】:2019-04-14 23:23:57
【问题描述】:

我对电话身份验证的正确流程有点困惑。 我注意到有几个场景我无法重现,因为我无法从 Firebase 中完全删除我的用户并重现所有场景。可能的情况是:

  1. 用户从未登录到 Firebase
  2. 用户之前登录并退出,登录时会收到短信
  3. 用户之前登录并退出,登录时未收到短信

发生在我身上的是场景 2。我的日志是:

D/DTAG: Asking verification for: +972052*****77
D/DTAG: 2. Sending for verification and waiting response to callbacks
D/DTAG: 3.b. Sending code
D/DTAG: 3.a. Verification complete, signing in
D/DTAG: signInWithCredential:success

问题 1:那么现在 SMS 是无关紧要的,对吧?不看短信验证码也能登录?

问题 2:在场景 1 中,根本没有调用回调“onVerificationCompleted”吗?

问题 3:在场景 3 中,根本没有调用回调“onCodeSent”?

问题 4:如何在“onCodeSent”检索短信代码?我知道我可以在“onVerificationCompleted”使用phoneAuthCredential.getSmsCode(),但有些情况下它没有被调用。

我的代码:

public class MyVerifyPhoneActivity extends AppCompatActivity {

    private static final String TAG = "DTAG";
    EditText editTextCode;
    Button buttonLogin;
    String mVerificationId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_verify_phone);

        editTextCode = findViewById(R.id.editTextCode);
        buttonLogin = findViewById(R.id.myButtonSignIn);

        String phonenumber = getIntent().getStringExtra("phonenumber");
        Log.d(TAG,"Asking verification for: "+phonenumber);
        sendVerificationCode(phonenumber);


        buttonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String code = editTextCode.getText().toString().trim();
                Log.d(TAG,"Button login clicked");

                if (code.isEmpty() || code.length() < 6) {

                    editTextCode.setError("Enter code...");
                    editTextCode.requestFocus();
                    return;
                }

                verifyCode(code);
            }
        });


    }

    private void sendVerificationCode(String number) {

        Log.d(TAG,"2. Sending for verification and waiting response to callbacks");
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                number,
                60,
                TimeUnit.SECONDS,
                TaskExecutors.MAIN_THREAD,
                mCallBack
        );

    }

    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallBack = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

        @Override
        public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {

            Log.d(TAG,"3.a. Verification complete, signing in");
            signInWithPhoneAuthCredential(phoneAuthCredential);
        }

        @Override
        public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
            super.onCodeSent(verificationId, forceResendingToken);

            mVerificationId = verificationId;
            Log.d(TAG,"3.b. Sending code");

        }

        @Override
        public void onVerificationFailed(FirebaseException e) {
            Log.w(TAG, "onVerificationFailed", e);
            Log.d(TAG,"3.c. Failed");

            if (e instanceof FirebaseAuthInvalidCredentialsException) {
                // Invalid request
                // ...
            } else if (e instanceof FirebaseTooManyRequestsException) {
                // The SMS quota for the project has been exceeded
                // ...
            }
        }
    };


    private void verifyCode(String code)
    {
        Log.d(TAG,"verifying Code");
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, code);
         signInWithPhoneAuthCredential(credential);
    }



    private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {

        FirebaseAuth.getInstance().signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d("DTAG", "signInWithCredential:success");

                    FirebaseUser user = task.getResult().getUser();

                } else {
                    // Sign in failed, display a message and update the UI
                    Log.w("DTAG", "signInWithCredential:failure", task.getException());
                    if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                        // The verification code entered was invalid
                    }
                }
            }
        });
    }


}

【问题讨论】:

  • 验证码仅在您验证的号码不在同一部手机中时发送。
  • 这对我来说不是这样,在使用手机 B 和手机 A 号码进行一些测试后,现在我每次在手机 A 和使用手机 A 时都会收到代码。

标签: android firebase firebase-authentication


【解决方案1】:

由于无法从 Firebase 中完全删除我的用户,我无法复制

-> 是的,你可以。看看图片。

问题 1 的答案: -> 不是。 SMS显然是相关的。没有短信,手机认证将无法工作。

问题2的答案: -> onVerificationCompleted 每次都会被调用。

问题3的答案: -> 是的。 onCodeSent 不是每次都被调用。

问题4的答案: -> onCodeSent 方法中不需要 OTP。我们可以在onCodeSent. 中获得verificationIdPhoneAuthProvider.ForceResendingToken,我们需要将verificationId 保存在一个变量中。并在身份验证用户输入 OTP 时使用它。

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(mVerificationId, YouEditTextValueString);

我的看法: 当我第一次工作时,我也有这些问题。我的经验是,如果我们使用相同的设备和相同的电话号码,SMS 不会来,我猜Firebasegoogle-play-service 处理它。

不知何故,现在我每次都收到相同设备和电话号码的短信。

但我们不需要关心它。

【讨论】:

    猜你喜欢
    • 2021-07-13
    • 1970-01-01
    • 2021-03-10
    • 2021-06-10
    • 2018-12-14
    • 2018-12-06
    • 1970-01-01
    相关资源
    最近更新 更多