0

I have made an Android application using Firebase Phone Authentication and Realtime Database.

My requirement is to first check if the user's no. is in my database or not and then send him the OTP.

My database: Employees node

My code:

rootRef= FirebaseDatabase.getInstance().getReference().child("Employees").child("mobno");

//---------------1----------------

getcodeBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("abcd","get code button clicked");
                if (!cugET.getText().toString().trim().isEmpty() && cugValidFlag==true) {
                    Log.d("abcd","entered no. is valid");
                    enteredcugno = cugET.getText().toString().trim();
                    Log.d("abcd","Entered cugno: "+enteredcugno);

                    rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            Log.d("abcd","rootRef listener reached");
                            if(dataSnapshot.child(enteredcugno).exists()){
                                Log.d("abcd","cugno exists in db");
                                startPhoneNumberVerification(cugET.getText().toString().trim());
                                mVerified = false;
                                otpTV.setVisibility(View.VISIBLE);
                                otpET.setVisibility(View.VISIBLE);
                                otpValTV.setVisibility(View.VISIBLE);
                                verifycodeBtn.setVisibility(View.VISIBLE);
                            }
                            else{
                                Log.d("abcd","cugno doesn't exists in db");
                                Toast.makeText(cugLogin.this,"No such CUG No. found",Toast.LENGTH_SHORT).show();
                            }
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
                }
        }
    });

//------------------------2--------------------

private void startPhoneNumberVerification(String phoneNumber) {
    Log.d("abcd","startPhoneNumberVerification");
    // [START start_phone_auth]
    PhoneAuthProvider.getInstance().verifyPhoneNumber(
            "+91"+phoneNumber,        // Phone number to verify
            60,                 // Timeout duration
            TimeUnit.SECONDS,   // Unit of timeout
            this,               // Activity (for callback binding)
            mCallbacks);        // OnVerificationStateChangedCallbacks
    // [END start_phone_auth]

}

//--------------3--------------------

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 verificaiton without
            //     user action.
            Log.d("abcd", "onVerificationCompleted:" + credential);

            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("abcd", "onVerificationFailed", e);

            if (e instanceof FirebaseAuthInvalidCredentialsException) {
                Log.d("abcd","verification failed cz of FirebaseAuthInvalidCredentialsException");
                Toast.makeText(cugLogin.this,"Verification Failed !! Invalied verification Code",Toast.LENGTH_SHORT).show();
            }
            else if (e instanceof FirebaseTooManyRequestsException) {
                Log.d("abcd","verification failed cz FirebaseTooManyRequestsException");
                Toast.makeText(cugLogin.this,"Verification Failed !! Too many request. Try after some time. ",Toast.LENGTH_SHORT);
            }

        }

        @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("abcd", "onCodeSent:" + verificationId);

            // Save verification ID and resending token so we can use them later
            mVerificationId = verificationId;
            mResendToken = token;
        }
    };

//----------------4---------------

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    Log.d("abcd","signInWithPhoneAuthCredential reached");
    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("abcd", "signInWithCredential:success");

                        FirebaseUser user = task.getResult().getUser();
                        mVerified = true;
                        timer.cancel();
                        timerTV.setVisibility(View.INVISIBLE);
                        cugET.setEnabled(false);
                        cugTV.setVisibility(View.INVISIBLE);
                        cugET.setVisibility(View.INVISIBLE);
                        getcodeBtn.setVisibility(View.INVISIBLE);
                        otpTV.setVisibility(View.INVISIBLE);
                        otpET.setVisibility(View.INVISIBLE);
                        otpValTV.setVisibility(View.INVISIBLE);
                        verifycodeBtn.setVisibility(View.INVISIBLE);
                        Intent intent = new Intent(cugLogin.this,Login.class);
                        intent.putExtra("cugnotoLogin",enteredcugno);
                        startActivity(intent);
                        Toast.makeText(cugLogin.this,"Successfully verified",Toast.LENGTH_SHORT).show();
                        // ...
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w("abcd", "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                            Toast.makeText(cugLogin.this,"Invalid OTP ! Please enter correct OTP",Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
}

The last log I see is "Entered cugno: 9876543210"

No error being shown, I am really confused how can I correct it?

If I remove the rootRef listener my code is working but I want to check the user in the database first. Also I am giving the correct path to the rootRef then why isn't it working?

EDIT

I got my code working but I am still a bit confused, I just moved my rootRef initialization in the getcodeBtn listener. But I already had it in my onStart() function so it should have been initialized there as well, if anyone knows the reason behind it please let me know.

LATEST EDIT

Now when I signed out, my code is again stuck at the rootRef listener, it isn't getting passed into it. Even after closing the app it isn't letting me in. It's the same thing happening again. It's like something got refreshed overnight and the app let me sign in and when I signed out, I am stuck again. Why is this happening?

Dpka
  • 246
  • 1
  • 3
  • 13
  • Where in your code are you login-in? – Alex Mamo Jun 12 '18 at 10:52
  • @AlexMamo In the rootRef listener I am starting the startPhoneNumberVerification(cugET.getText().toString().trim()); and then it goes to mCallbacks and so on. My requirement was to first check if the user exists in the DB and then only send the OTP – Dpka Jun 12 '18 at 10:54
  • [Here](https://stackoverflow.com/questions/47893328/checking-if-a-particular-value-exists-in-the-firebase-database/47893879) is how you can check if a users exist in the database. – Alex Mamo Jun 12 '18 at 10:56
  • I had achieved that, it was all working fine, I just changed the logout code and when I logged out, since then I am not able to log in, as the code doesn't enter the rootRef Listener – Dpka Jun 12 '18 at 10:58
  • @AlexMamo What does FirebaseAuth.getInstance().signout() do? Can it be the reason for the problem or not? – Dpka Jun 12 '18 at 11:05
  • 1
    Using the first code snippet, you aren't login-out at all, you are just finishing an activity. Using the second, you are login-out. `FirebaseAuth.getInstance().signout()` is helping you do that. Why you cannot login again, it is another problem that cannot be solved using the code that you shared. – Alex Mamo Jun 12 '18 at 11:06
  • okay, what code snippet you would like to see then? – Dpka Jun 12 '18 at 11:07
  • The code where are you actually login-in. – Alex Mamo Jun 12 '18 at 11:14
  • @AlexMamo please check my Edits. – Dpka Jun 12 '18 at 11:23
  • Does your `FirebaseException e` return somethig? – Alex Mamo Jun 12 '18 at 11:46
  • @AlexMamo no nothing, Logs i get: 1. Firebase app initialised, 2. mAuth initialised, 3. mCallbacks initialisation reached, 4. cugno length is 10, 5. get code button clicked, 6. entered no. is valid, 7. Entered cugno: 9876543210 – Dpka Jun 12 '18 at 11:51
  • @AlexMamo found anything? :/ – Dpka Jun 12 '18 at 15:06
  • @AlexMamo the code is working if I remove the rootRef listener; I am giving the correct path in the rootRef, then why is that not working? – Dpka Jun 12 '18 at 15:43
  • @AlexMamo please check my latest edit, something is happening due to signout. – Dpka Jun 13 '18 at 09:40

1 Answers1

0

I solved it, it wasn't the coding problem but the logic was faulty. I set the rules of the database for the authenticated users only, and was checking my database first to let the user to sign in, so when I logged out, the code went into a loop as it couldn't access the database to let the user sign in.

Dpka
  • 246
  • 1
  • 3
  • 13