首页 > 解决方案 > 使用现有用户登录应用程序 - phone Auth Firebase Android -

问题描述

我正在开发一个使用 firebase phone auth 方法的应用程序。它适用于第一次使用的用户,他们获得短信代码并在 firebase 控制台中注册。但是,如果他们注销或重新安装应用程序,他们将无法访问应用程序菜单,因为它们已经在 firebase 控制台数据库中。

我不知道如何告诉应用程序用户是否已经注册,然后对主要活动进行意图,如果未注册,则转到注册活动。我知道如何获取当前用户,但如果用户存在于 firebase 数据库中,我不知道如何跳过验证步骤。

希望你能得到我。

这是我的代码。


    private static final String KEY = "userAuth";
    private static final String TAG = "PhoneAuthActivity";
    private static final String KEY_VERIFY_IN_PROGRESS = "key_verify_in_progress";

    // [START declare_auth]
    private FirebaseAuth mAuth;
    // [END declare_auth]

    private boolean mVerificationInProgress = false;
    private String mVerificationId;
    private PhoneAuthProvider.ForceResendingToken mResendToken;
    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;

    // Instance of Firebase
    private PhoneAuthProvider phoneAuthProvider;

    private String verificationId;
    // id user from DB
    private String idUser;

    private EditText activationCode;
    private ProgressBar progressBar;

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

        // 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]

                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) {

                } 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();
                    // [END_EXCLUDE]
                }
            }

            @Override
            public void onCodeSent(@NonNull String verificationId,
                                   @NonNull 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;
            }
        };
        // [END phone_auth_callbacks]

        activationCode = findViewById(R.id.eTextActivCode);
        progressBar = findViewById(R.id.progressBar);

        String phone = getIntent().getStringExtra("phone");
        idUser = getIntent().getStringExtra("user");
        sendVerificationCode(phone);
    }

    // [START on_start_check_user]
    @Override
    public void onStart() {
        super.onStart();
        // Check if user is signed in (non-null) and update UI accordingly.
        FirebaseUser currentUser = mAuth.getCurrentUser();
        if(currentUser != null){
            Intent intent = new Intent(VerifyCodeActivity.this, MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            intent.putExtra("user", idUser);
            startActivity(intent);
        }

        // [START_EXCLUDE]
        if (mVerificationInProgress) {
            startPhoneNumberVerification(getIntent().getStringExtra("phone"));
        }
        // [END_EXCLUDE]
    }
    // [END on_start_check_user]

    @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()) {
                            if (task.isSuccessful() || activationCode.equals("123456")) {
                                Intent intent = new Intent(VerifyCodeActivity.this, MainActivity.class);
                                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                                intent.putExtra("user", idUser);
                                startActivity(intent);
                            } else {
                                Toast.makeText(VerifyCodeActivity.this, task.getException().getMessage(),
                                        Toast.LENGTH_LONG).show();
                            }
                        } 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]
                                activationCode.setError("Ingresa un código válido.");
                                // [END_EXCLUDE]
                            }
                        }
                    }
                });
    }
    // [END sign_in_with_phone]


    public void verifyPhoneNumber(View view) {
        String code = activationCode.getText().toString();

        if (code.isEmpty() || code.length() < 6) {
            activationCode.setError("Ingresa un código correcto");
            activationCode.requestFocus();
            return;
        }
        verifyPhoneNumberWithCode(mVerificationId, code);
    }

    public void resendActivationCode(View view){
        resendVerificationCode(getIntent().getStringExtra("phone"), mResendToken);
    }

    private void sendVerificationCode(String number) {
        // Initialize Firebase Auth
        phoneAuthProvider = PhoneAuthProvider.getInstance();

        phoneAuthProvider.verifyPhoneNumber(number, 60, TimeUnit.SECONDS,
                TaskExecutors.MAIN_THREAD, mCallback);
    }

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

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

                @Override
                public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
                    String code = phoneAuthCredential.getSmsCode();

                    if (code != null) {
                        progressBar.setVisibility(View.VISIBLE);
                        //verifyCode(code);
                    }
                }

                @Override
                public void onVerificationFailed(FirebaseException e) {
                    Toast.makeText(VerifyCodeActivity.this,
                            "Error al verificar el número de teléfono: " + e.getMessage(),
                            Toast.LENGTH_LONG).show();
                }
            };
} ```

标签: javaandroidfirebase-authentication

解决方案


取决于您的问题和评论,您需要知道用户之前是否已经登录或者是第一次登录,并且您没有服务器数据库来保存用户数据

但是如果你使用另一个服务器数据库,我会给你两个答案

注意:在您的问题中,您写的是您希望用户在第二次登录时进入菜单活动而无需验证但依赖是不可能发生的,因为这样任何人都可以使用任何电话号码并登录,所以使用电话的验证码就像密码和电子邮件以确保身份验证成功

1.第一个解决方案:如果您在第一次用户登录时有另一个数据库服务器,您将在您的数据库中保存用户数据,如姓名和电话、位置、uid ......等,这样您就可以通过uid将用户 bwtween firebase phone auth 与数据库绑定或电话,现在当用户第二次通过firebase登录时,您将通过uid或电话检查用户是否已经在您的数据库中(不是第一次)或不是(用户第一次)。

  1. 第二种解决方案:使用AdditionalUserInfo检查用户是 newUser 还是在尝试进入signInWithCredential内部之前登录onComplete

像这样

OnCompleteListener<AuthResult> completeListener = new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            if (task.isSuccessful()) {
                boolean isNew = task.getResult().getAdditionalUserInfo().isNewUser();
                Log.d("MyTAG", "onComplete: " + (isNew ? "new user" : "old user"));
            }
        }
    };

我希望这对你有帮助


推荐阅读