Android Firebase电话认证流程

Android Firebase电话认证流程,android,firebase,firebase-authentication,Android,Firebase,Firebase Authentication,我对电话认证的正确流程有点困惑。 我注意到有几个场景我无法重现,因为我无法从Firebase中完全删除我的用户并重现所有场景。可能的情况是: 用户从未登录到firebase 用户以前登录并注销,登录时收到短信 用户以前登录并注销,登录时未收到短信 发生在我身上的是场景2。我的日志是: D/DTAG: Asking verification for: +972052*****77 D/DTAG: 2. Sending for verification and waiting response to

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

  • 用户从未登录到firebase
  • 用户以前登录并注销,登录时收到短信
  • 用户以前登录并注销,登录时未收到短信
  • 发生在我身上的是场景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:所以现在短信是不相关的,对吗?我可以不检查短信代码就登录吗

    问题2:在场景1中,是否根本不调用回调“onVerificationCompleted”

    问题3:在场景3中,根本不调用回调“oncocent”

    问题4:如何在“OnCosent”检索SMS代码?。我知道我可以在“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
                        }
                    }
                }
            });
        }
    
    
    }
    
    公共类MyVerifyPhoneActivity扩展了AppCompatActivity{
    私有静态最终字符串TAG=“DTAG”;
    编辑文本编辑文本代码;
    按钮式按钮;
    字符串mvericationid;
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\u my\u verify\u phone);
    editTextCode=findViewById(R.id.editTextCode);
    buttonLogin=findViewById(R.id.myButtonSignIn);
    字符串phonenumber=getIntent().getStringExtra(“phonenumber”);
    Log.d(标签“请求验证:”+电话号码);
    sendVerificationCode(电话号码);
    buttonLogin.setOnClickListener(新视图.OnClickListener(){
    @凌驾
    公共void onClick(视图v){
    字符串代码=editTextCode.getText().toString().trim();
    Log.d(标记“单击按钮登录”);
    if(code.isEmpty()| code.length()<6){
    setError(“输入代码…”);
    editTextCode.requestFocus();
    返回;
    }
    验证码(code);
    }
    });
    }
    私有void sendVerificationCode(字符串编号){
    Log.d(标记“2.发送验证并等待回调响应”);
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
    数字,
    60,
    时间单位:秒,
    TaskExecutors.MAIN_线程,
    麦卡贝克
    );
    }
    私有PhoneAuthProvider.OnVerificationStateChangedCallbacks McCallback=新PhoneAuthProvider.OnVerificationStateChangedCallbacks(){
    @凌驾
    已完成验证的公共无效(PhoneAuthCredential PhoneAuthCredential){
    日志d(标签“3.a.验证完成,登录”);
    使用phoneAuthCredential(phoneAuthCredential)登录;
    }
    @凌驾
    public void onCodeSent(字符串验证ID,PhoneAuthProvider.ForceResendingToken ForceResendingToken){
    super.oncodesnt(验证ID、forceResendingToken);
    mvericationId=验证ID;
    Log.d(标签“3.b.发送代码”);
    }
    @凌驾
    public void onVerificationFailed(FirebaseException e){
    Log.w(标签“onVerificationFailed”,e);
    Log.d(标签“3.c.失败”);
    if(例如FirebaseAuthInvalidCredentialsException实例){
    //无效请求
    // ...
    }else if(例如FirebaseTooManyRequestsException的实例){
    //已超过项目的SMS配额
    // ...
    }
    }
    };
    专用无效验证码(字符串码)
    {
    Log.d(标签“验证代码”);
    PhoneAuthCredential credential=PhoneAuthProvider.getCredential(mvericationId,代码);
    使用PhoneAuthCredential(凭证)登录;
    }
    使用PhoneAuthCredential(PhoneAuthCredential凭据)的专用无效登录{
    FirebaseAuth.getInstance().signInWithCredential(凭证).addOnCompleteListener(这是新的OnCompleteListener()){
    @凌驾
    未完成的公共void(@NonNull任务){
    if(task.issusccessful()){
    //登录成功,使用登录用户的信息更新UI
    Log.d(“DTAG”,“使用凭证登录:成功”);
    FirebaseUser=task.getResult().getUser();
    }否则{
    //登录失败,显示消息并更新UI
    Log.w(“DTAG”,“signInWithCredential:failure”,task.getException());
    if(FirebaseAuthInvalidCredentialsException的task.getException()实例){
    //输入的验证码无效
    }
    }
    }
    });
    }
    }
    
    我无法复制,因为我无法从Firebase中完全删除我的用户

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

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

    问题2的答案: ->
    每次都将调用onVerificationCompleted

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

    问题4的答案: ->您不需要在
    oncodesnt
    方法中使用OTP。我们可以在
    onconsent中获取
    verificationId
    PhoneAuthProvider.ForceResendingToken
    我们需要在变量中保存
    verificationId
    。并在身份验证用户输入OTP时使用它。