Neeraj Sewani
Neeraj Sewani

Reputation: 4287

How to check whether a user is email verified or not through a listener?

I have got an activity EmailSignUpActivity, it has two buttons, one to create a user and another one to verify the email. After a user is created, the Verify Email button would be pressed by the user which would send the verification email to the registered email.

What I am doing here is keeping the user to the EmailSignUpActivity till he verifies the email and then send him to the MainActivity. To achieve that I am using the following code:

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

The above code has a while loop after the documentation comments that would run infinitely till the email is verified but this is making the app unresponsive like:enter image description here

I tried to achieve the same thing with the help of AuthStateListener but failed as AuthStateListener would only get triggered when a user is created, signed in, signed out.

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

What I want here is to listen to isEmailVerified() through a listener or any equivalent to that which shouldn't make the app unresponsive. How can I achieve this?

Upvotes: 0

Views: 977

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598728

As you've discovered, using a so-called tight infinite loop will stop your app from responding to other user input. So we can easily agree that is a bad idea. If it was suggested that you do so in the Firebase documentation, can you give me a link to that specific piece of the documentation?

You will need to find another event to respond to, to verify that the user has verified their email address. Common options are:

  1. Give the user a UI element to indicate they've verified their email address. This might not be possible in your situation, but it is the most common approach that I know off.
  2. Check whether the email address is verified on startup or when your main activity show. This typically goes into your sign-in flow: sign in the user, check if their email address is verified. If so, you let them into the app. If not, you give them the option to (re)send the verification email. Given that the user will need to toggle to their mail app to get the verification email, they're already toggling out of (and thus back into) your app anyway.
  3. Specify a so-called continue URL in with the verification email. If you use this option to send a Firebase Dynamic Link, you can automatically get the user back into your application where they left off, after they click the verification link in the email (as long as they do so on the same mobile device).
  4. Check the periodically. This is most similar to what you do now, but then without the tight loop. See this question for some options for this: How to run a method every X seconds

Upvotes: 1

Related Questions