如何通过侦听器检查用户是否已通过电子邮件验证?

时间:2018-08-01 12:22:28

标签: android firebase firebase-authentication

我有一个活动 EmailSignUpActivity ,它有两个按钮,一个用于创建用户,另一个用于验证电子邮件。创建用户后,用户将按下验证电子邮件按钮,该按钮会将验证电子邮件发送到注册电子邮件。

我在这里所做的是让用户使用 EmailSignUpActivity ,直到他验证电子邮件,然后将其发送到 MainActivity 。为此,我使用以下代码:

//  sending email verification
    emailVerificationButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            progressDialog1.show();

            if(mAuth.getCurrentUser() != null) {

                if (emailEditText.length() != 0 && passwordEditText.length() != 0 && reEnterPasswordEditText.length() != 0) {
                        mAuth.getCurrentUser().sendEmailVerification().addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                progressDialog1.dismiss();

                                Log.d(TAG, "onSuccess: email sent");

                                Toast.makeText(EmailSignUpActivity.this, "Email verification sent", Toast.LENGTH_SHORT).show();

                                /**
                                 * Making the app unresponsive
                                 */
                                while(!mAuth.getCurrentUser().isEmailVerified()){
                                    mAuth.getCurrentUser().reload();
                                }

                                if(mAuth.getCurrentUser().isEmailVerified()){
                                    Toast.makeText(EmailSignUpActivity.this, "Email verified", Toast.LENGTH_SHORT).show();
                                    Intent intent = new Intent(EmailSignUpActivity.this, MainActivity.class);
                                    startActivity(intent);
                                    finish();
                                }
                            }
                        }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                progressDialog1.dismiss();

                                Log.w(TAG, "onFailure: Email verification failed ==> ", e);
                            }
                        });
                    }else{
                    Toast.makeText(EmailSignUpActivity.this, "Fill out the details", Toast.LENGTH_SHORT).show();
                }
            }else{
                Toast.makeText(EmailSignUpActivity.this, "Create a user first!", Toast.LENGTH_SHORT).show();
            }
            }
        });

上面的代码在文档注释之后会循环播放一段时间,这些注释将无限运行直到电子邮件被验证,但这会使应用程序无响应,例如:enter image description here

我尝试在 AuthStateListener 的帮助下实现相同的目标,但是失败了,因为 AuthStateListener 仅在创建用户时才会触发, 已登录已退出

authStateListener = new FirebaseAuth.AuthStateListener() {
        @Override
        public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {

            Log.d(TAG, "onAuthStateChanged: method called");

            if(firebaseAuth.getCurrentUser() != null)
                isEmailVerified = firebaseAuth.getCurrentUser().isEmailVerified();

            if(isEmailVerified){
                Toast.makeText(EmailSignUpActivity.this, "Email verified", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(EmailSignUpActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        }
    };

    mAuth.addAuthStateListener(authStateListener);

我在这里想要通过侦听器或与之等效的任何方法侦听 isEmailVerified(),这不应使应用程序无响应。我该如何实现?

1 个答案:

答案 0 :(得分:1)

正如您所发现的那样,使用所谓的紧密无限循环将阻止您的应用响应其他用户输入。因此,我们很容易同意这是一个坏主意。如果在Firebase文档中建议您这样做,可以给我链接到该文档的特定部分吗?

您将需要找到另一个事件进行响应,以验证用户是否已验证其电子邮件地址。常用选项是:

  1. 为用户提供一个UI元素,以指示他们已验证其电子邮件地址。在您的情况下,这可能是不可能的,但这是我所知道的最常见的方法。
  2. 检查在启动时或显示主活动时是否已验证电子邮件地址。这通常会进入您的登录流程:登录用户,检查其电子邮件地址是否已验证。如果是这样,则让他们进入应用程序。如果没有,您可以给他们选择(重新)发送验证电子邮件的选项。鉴于用户需要切换到他们的邮件应用程序以获取验证电子邮件,因此他们无论如何已经跳出(从而又重新回到了)您的应用程序。
  3. 在验证电子邮件中指定一个所谓的continue URL。如果您使用此选项发送Firebase动态链接,您可以在用户单击电子邮件中的验证链接后(只要他们在同一移动设备上这样做),就可以自动将用户重新带回应用程序。
  4. 定期检查。这与您现在所做的最相似,但是没有 tight 循环。有关此问题的一些选项,请参见此问题:How to run a method every X seconds