【问题标题】:OTP not sent in Firebase Authentication app using both email and contact number verification未使用电子邮件和联系号码验证在 Firebase 身份验证应用中发送 OTP
【发布时间】:2019-02-17 11:13:00
【问题描述】:

我正在 Android Studio 中制作一个应用,用户必须先验证他的联系电话和电子邮件地址,然后才能将他的详细信息上传到 Firebase 实时数据库。我首先验证电子邮件地址,然后继续进行联系号码验证。电子邮件地址验证工作正常,但联系号码验证不行。这是我用于联系号码验证的代码:

public class OtpActivity extends AppCompatActivity {

    TextView otpAppear;
    TextInputLayout contactVer;
    CountryCodePicker ccpVer;
    Button otpGet;
    String mVerificationId;
    PhoneAuthProvider.ForceResendingToken forceResendingToken;
    //PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
    FirebaseAuth auth;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_otp);

        contactVer=findViewById(R.id.verifyContact);
        otpAppear=findViewById(R.id.appearOtp);
        otpGet=findViewById(R.id.getOtp);
        ccpVer=findViewById(R.id.ccpVerify);

        ccpVer.registerCarrierNumberEditText(contactVer.getEditText());


        /*otpGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String verCont=ccpVer.getFullNumberWithPlus();

                PhoneAuthProvider.getInstance().verifyPhoneNumber(verCont,120, TimeUnit.SECONDS,OtpActivity.this,mCallbacks,forceResendingToken);

                GetOtp();
            }
        });*/
    }
    public void sendOtp(View view)
    {
        SharedPreferences pref1= PreferenceManager.getDefaultSharedPreferences(OtpActivity.this);
        String number=pref1.getString("contact",null);

        //verifyContact.setText(number);

        ccpVer.registerCarrierNumberEditText(contactVer.getEditText());
        String verCont=ccpVer.getFullNumberWithPlus();

        PhoneAuthProvider.getInstance().verifyPhoneNumber(verCont,120, TimeUnit.SECONDS,OtpActivity.this,mCallbacks,forceResendingToken);
    }
    //auth=FirebaseAuth.getInstance();
    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks=new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        @Override
        public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
                String code=phoneAuthCredential.getSmsCode();
                otpAppear.setText(code);
                if(otpAppear!=null)
                {
                    //otpAppear.setText(code);
                    Toast.makeText(OtpActivity.this, "Contact Verified !!!", Toast.LENGTH_LONG).show();
                }
                else
                    Toast.makeText(OtpActivity.this, "Contact Couldn't Be Verified !!!", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onVerificationFailed(FirebaseException e) {
            Toast.makeText(OtpActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
        }

        @Override
        public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
            super.onCodeSent(s, forceResendingToken);
            mVerificationId = s;
            PhoneAuthProvider.ForceResendingToken token=forceResendingToken;
            Toast.makeText(OtpActivity.this, "Code Sent !!!", Toast.LENGTH_LONG).show();
        }
    };
    /*private void GetOtp()
    {
        auth=FirebaseAuth.getInstance();
        mCallbacks=new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
                String code=phoneAuthCredential.getSmsCode();
                if(code!=null)
                {
                    otpAppear.setText(code);
                    Toast.makeText(OtpActivity.this, "Contact Verified !!!", Toast.LENGTH_LONG).show();
                }
                else
                    Toast.makeText(OtpActivity.this, "Contact Couldn't Be Verified !!!", Toast.LENGTH_LONG).show();
            }

            @Override
            public void onVerificationFailed(FirebaseException e) {
                Toast.makeText(OtpActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
            }

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

                mVerificationId = s;
                PhoneAuthProvider.ForceResendingToken token=forceResendingToken;
                Toast.makeText(OtpActivity.this,"Code sent",Toast.LENGTH_LONG).show();
            }
        };

    }*/
}

我将 sendOtp 方法放在 getOtp 按钮的 onClick 中。当我单击按钮时,它会显示 Toast 消息“联系已验证!!!”甚至没有发送 OTP。请帮我解决一下。

【问题讨论】:

    标签: android firebase firebase-authentication


    【解决方案1】:

    您可以使用此代码

    public class PHONE_ACTIVITY extends AppCompatActivity {
    
    private static final String TAG = "PhoneAuthActivity";
    
    private static final String KEY_VERIFY_IN_PROGRESS = "key_verify_in_progress";
    
    private static final int STATE_INITIALIZED = 1;
    private static final int STATE_CODE_SENT = 2;
    private static final int STATE_VERIFY_FAILED = 3;
    private static final int STATE_VERIFY_SUCCESS = 4;
    private static final int STATE_SIGNIN_FAILED = 5;
    private static final int STATE_SIGNIN_SUCCESS = 6;
    @BindView(R.id.fieldPhoneNumber)
    EditText fieldPhoneNumber;
    @BindView(R.id.fieldVerificationCode)
    EditText fieldVerificationCode;
    @BindView(R.id.buttonStartVerification)
    Button buttonStartVerification;
    @BindView(R.id.buttonVerifyPhone)
    Button buttonVerifyPhone;
    @BindView(R.id.buttonResend)
    Button buttonResend;
    @BindView(R.id.phone_result)
    TextView phoneResult;
    @BindView(R.id.phone_email)
    TextView phoneEmail;
    @BindView(R.id.phone_phone)
    TextView phonePhone;
    @BindView(R.id.phone_name)
    TextView phoneName;
    @BindView(R.id.phone_image)
    ImageView phoneImage;
    
    // [START declare_auth]
    private FirebaseAuth mAuth;
    // [END declare_auth]
    
    private boolean mVerificationInProgress = false;
    private String mVerificationId;
    private PhoneAuthProvider.ForceResendingToken mResendToken;
    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_phone__activity);
        ButterKnife.bind(this);
    
        // Restore instance state
        if (savedInstanceState != null) {
            onRestoreInstanceState(savedInstanceState);
        }
    
        // [START initialize_auth]
        // Initialize Firebase Auth
        mAuth = FirebaseAuth.getInstance();
        // [END initialize_auth]
    
        // Initialize phone auth callbacks
        // [START phone_auth_callbacks]
        mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
    
            @Override
            public void onVerificationCompleted(PhoneAuthCredential credential) {
                // This callback will be invoked in two situations:
                // 1 - Instant verification. In some cases the phone number can be instantly
                //     verified without needing to send or enter a verification code.
                // 2 - Auto-retrieval. On some devices Google Play services can automatically
                //     detect the incoming verification SMS and perform verification without
                //     user action.
                Log.d(TAG, "onVerificationCompleted:" + credential);
                // [START_EXCLUDE silent]
                mVerificationInProgress = false;
                // [END_EXCLUDE]
    
                // [START_EXCLUDE silent]
                // Update the UI and attempt sign in with the phone credential
                updateUI(STATE_VERIFY_SUCCESS, credential);
                // [END_EXCLUDE]
                signInWithPhoneAuthCredential(credential);
            }
    
            @Override
            public void onVerificationFailed(FirebaseException e) {
                // This callback is invoked in an invalid request for verification is made,
                // for instance if the the phone number format is not valid.
                Log.w(TAG, "onVerificationFailed", e);
                // [START_EXCLUDE silent]
                mVerificationInProgress = false;
                // [END_EXCLUDE]
    
                if (e instanceof FirebaseAuthInvalidCredentialsException) {
                    // Invalid request
                    // [START_EXCLUDE]
                    phoneResult.setError("Invalid phone number.");
                    // [END_EXCLUDE]
                } else if (e instanceof FirebaseTooManyRequestsException) {
                    // The SMS quota for the project has been exceeded
                    // [START_EXCLUDE]
                    /*Snackbar.make(findViewById(android.R.id.content), "Quota exceeded.",
                            Snackbar.LENGTH_SHORT).show();*/
                    phoneResult.setError("Quota exceeded.");
                    // [END_EXCLUDE]
                }
    
                // Show a message and update the UI
                // [START_EXCLUDE]
                updateUI(STATE_VERIFY_FAILED);
                // [END_EXCLUDE]
            }
    
            @Override
            public void onCodeSent(String verificationId,
                                   PhoneAuthProvider.ForceResendingToken token) {
                // The SMS verification code has been sent to the provided phone number, we
                // now need to ask the user to enter the code and then construct a credential
                // by combining the code with a verification ID.
                Log.d(TAG, "onCodeSent:" + verificationId);
    
                // Save verification ID and resending token so we can use them later
                mVerificationId = verificationId;
                mResendToken = token;
    
                // [START_EXCLUDE]
                // Update UI
                updateUI(STATE_CODE_SENT);
                // [END_EXCLUDE]
            }
        };
        // [END phone_auth_callbacks]
    }
    
    @OnClick({R.id.buttonStartVerification, R.id.buttonVerifyPhone, R.id.buttonResend})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.buttonStartVerification:
    
                if (!validatePhoneNumber()) {
                    Toast.makeText(PHONE_ACTIVITY.this, "PHONE NUMBER NOT VALIDATE", Toast.LENGTH_SHORT).show();
                    /*Log.d(TAG,"PHONE NUMBER NOT VALIDATE");*/
                    return;
                }
    
                startPhoneNumberVerification(fieldPhoneNumber.getText().toString());
                break;
            case R.id.buttonVerifyPhone:
                String code = fieldVerificationCode.getText().toString();
                if (TextUtils.isEmpty(code)) {
                    fieldVerificationCode.setError("Cannot be empty.");
                    return;
                }
    
                verifyPhoneNumberWithCode(mVerificationId, code);
                break;
            case R.id.buttonResend:
                resendVerificationCode(fieldPhoneNumber.getText().toString(), mResendToken);
                break;
        }
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(KEY_VERIFY_IN_PROGRESS, mVerificationInProgress);
    }
    
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mVerificationInProgress = savedInstanceState.getBoolean(KEY_VERIFY_IN_PROGRESS);
    }
    
    private void startPhoneNumberVerification(String phoneNumber) {
        // [START start_phone_auth]
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                phoneNumber,        // Phone number to verify
                60,                 // Timeout duration
                TimeUnit.SECONDS,   // Unit of timeout
                this,               // Activity (for callback binding)
                mCallbacks);        // OnVerificationStateChangedCallbacks
        // [END start_phone_auth]
    
        mVerificationInProgress = true;
    }
    
    private void verifyPhoneNumberWithCode(String verificationId, String code) {
        // [START verify_with_code]
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
        // [END verify_with_code]
        signInWithPhoneAuthCredential(credential);
    }
    
    // [START resend_verification]
    private void resendVerificationCode(String phoneNumber,
                                        PhoneAuthProvider.ForceResendingToken token) {
        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                phoneNumber,        // Phone number to verify
                60,                 // Timeout duration
                TimeUnit.SECONDS,   // Unit of timeout
                this,               // Activity (for callback binding)
                mCallbacks,         // OnVerificationStateChangedCallbacks
                token);             // ForceResendingToken from callbacks
    }
    // [END resend_verification]
    
    // [START sign_in_with_phone]
    private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
        mAuth.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(TAG, "signInWithCredential:success");
    
                            FirebaseUser user = task.getResult().getUser();
                            // [START_EXCLUDE]
                            updateUI(STATE_SIGNIN_SUCCESS, user);
                            // [END_EXCLUDE]
                        } else {
                            // Sign in failed, display a message and update the UI
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                                // The verification code entered was invalid
                                // [START_EXCLUDE silent]
                                phoneResult.setError("Invalid code.");
                                // [END_EXCLUDE]
                            }
                            // [START_EXCLUDE silent]
                            // Update UI
                            updateUI(STATE_SIGNIN_FAILED);
                            // [END_EXCLUDE]
                        }
                    }
                });
    }
    // [END sign_in_with_phone]
    
    private void signOut() {
        mAuth.signOut();
        updateUI(STATE_INITIALIZED);
    }
    
    private void updateUI(int uiState) {
        updateUI(uiState, mAuth.getCurrentUser(), null);
    }
    
    private void updateUI(FirebaseUser user) {
        if (user != null) {
            updateUI(STATE_SIGNIN_SUCCESS, user);
        } else {
            updateUI(STATE_INITIALIZED);
        }
    }
    
    private void updateUI(int uiState, FirebaseUser user) {
        updateUI(uiState, user, null);
    }
    
    private void updateUI(int uiState, PhoneAuthCredential cred) {
        updateUI(uiState, null, cred);
    }
    
    private void updateUI(int uiState, FirebaseUser user, PhoneAuthCredential cred) {
        switch (uiState) {
            case STATE_INITIALIZED:
                // Initialized state, show only the phone number field and start button
                enableViews(buttonStartVerification, fieldPhoneNumber);
                disableViews(buttonVerifyPhone, buttonResend, fieldVerificationCode);
                //mDetailText.setText(null);
                break;
            case STATE_CODE_SENT:
                // Code sent state, show the verification field, the
                enableViews(buttonVerifyPhone, buttonResend, fieldPhoneNumber, fieldVerificationCode);
                disableViews(buttonStartVerification);
                phoneResult.setText("CODE SENT");
                break;
            case STATE_VERIFY_FAILED:
                // Verification has failed, show all options
                enableViews(buttonStartVerification, buttonVerifyPhone, buttonResend, fieldPhoneNumber,
                        fieldVerificationCode);
                phoneResult.setText("VERIFICATION FAILED");
                break;
            case STATE_VERIFY_SUCCESS:
                // Verification has succeeded, proceed to firebase sign in
                disableViews(buttonStartVerification, buttonVerifyPhone, buttonResend, fieldPhoneNumber,
                        fieldVerificationCode);
                phoneResult.setText("succeeded");
    
                // Set the verification text based on the credential
                if (cred != null) {
                    if (cred.getSmsCode() != null) {
                        fieldVerificationCode.setText(cred.getSmsCode());
                    } else {
                        fieldVerificationCode.setText("ok");
                    }
                }
    
                break;
            case STATE_SIGNIN_FAILED:
                // No-op, handled by sign-in check
                phoneResult.setText("SIGN IN FAILED");
                break;
            case STATE_SIGNIN_SUCCESS:
                // Np-op, handled by sign-in check
                break;
        }
    
        if (user == null) {
        } else {
            // Signed in
            //phoneResult.setText(user.getPhoneNumber());
            phoneEmail.setText(user.getEmail());
            phoneName.setText(user.getDisplayName());
            phonePhone.setText(user.getPhoneNumber());
            GlideApp.with(PHONE_ACTIVITY.this)
                    .load(user.getPhotoUrl())
                    .into(phoneImage);
    
        }
    }
    
    private boolean validatePhoneNumber() {
        String phoneNumber = fieldPhoneNumber.getText().toString();
        if (TextUtils.isEmpty(phoneNumber)) {
            phoneResult.setError("Invalid phone number.");
            return false;
        }
    
        return true;
    }
    
    private void enableViews(View... views) {
        for (View v : views) {
            v.setEnabled(true);
        }
    }
    
    private void disableViews(View... views) {
        for (View v : views) {
            v.setEnabled(false);
        }
    }
    }
    

    【讨论】:

    • 但我不想登录用户。我只希望他们验证他们的联系电话。那么这可以做到吗?您还可以建议我可以在我的代码中进行的任何修改,因为我不只是想复制您的代码。我也想从我犯的错误中吸取教训。因此,如果您能指出我所犯的任何错误并提出一些解决方案,我将不胜感激。
    • 如果您在登录后获得令牌,则您的号码已通过验证。还有一点,您的观点不明确且错误,因此我无法修改您的代码。如果您清理代码,那么我可能会尝试
    • 你的意思是如果我从我的问题中删除我的代码,那么你可能会尝试对吗?
    猜你喜欢
    • 2022-08-07
    • 2018-08-07
    • 2018-02-10
    • 2016-11-27
    • 2019-12-01
    • 2019-07-13
    • 2020-05-11
    • 2021-09-05
    • 2019-07-13
    相关资源
    最近更新 更多