Firebase电话身份验证流程

时间:2018-11-12 09:02:25

标签: android firebase firebase-authentication

对于电话认证的正确流程,我有点困惑。 我已经注意到,由于无法完全从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无关紧要了,对吧?我可以在不检查SMS代码的情况下登录吗?

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

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

问题4 :如何在“ onCodeSent”处检索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
                    }
                }
            }
        });
    }


}

1 个答案:

答案 0 :(得分:2)

  

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

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

Firebase console.

问题1的答案-> 不是。短信显然是相关的。没有短信,电话身份验证将不起作用。

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

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

问题4的答案: -> 您不需要使用onCodeSent方法进行OTP。我们可以在verificationId中获得PhoneAuthProvider.ForceResendingTokenonCodeSent.,我们需要将verificationId保存在变量中。并在验证用户输入OTP时使用它。

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

我的观点: 当我第一次工作时,我也想到了这些问题。我经历过,如果我们使用具有相同电话号码的同一设备,则短信不会发送,我猜Firebasegoogle-play-service会处理它。

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

但是我们不需要关心它。