You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Firebase项目:如何修改代码实现仅存量用户OTP登录验证

Solution: Restrict OTP to Existing Firebase Realtime Database Users

Hey there! Let's fix this issue where your app sends OTPs to any phone number—even if the user isn't in your existing database. Here's how to adjust your code to only let pre-registered users proceed with login:

Key Change: Check User Existence Before Sending OTP

The core fix is adding a database check before starting the OTP process. We'll verify if the provided phone number exists in your Firebase Realtime Database first, and only send the OTP if it does.

Step-by-Step Code Modifications

  1. Add Required Imports
    First, add these imports at the top of your file to handle Firebase Database listeners:

    import com.google.firebase.database.DataSnapshot;
    import com.google.firebase.database.DatabaseError;
    import com.google.firebase.database.ValueEventListener;
    
  2. Initialize Database Reference
    Make sure your Firebase Database reference is set up properly in onCreate:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        // ... existing view hooks ...
        
        // Initialize Firebase Database reference (update "users" to your actual node name)
        database = FirebaseDatabase.getInstance();
        reference = database.getReference("users");
    }
    
  3. Rewrite the sendOtp Method
    Update the sendOtp method to include the database check before sending the OTP. Choose the query that matches your database structure:

    public void sendOtp(View view){
        if(mobileNumber.getText().toString().equals("")){
            errorMessage.setText("Please Enter phone number");
            errorMessage.setVisibility(View.VISIBLE);
        }else if(mobileNumber.getText().toString().length() != 10){
            errorMessage.setText("PhoneNumber is Invalid");
            errorMessage.setVisibility(View.VISIBLE);
        }else{
            final String phoneNum= "+91"+mobileNumber.getText().toString();
            
            // Option 1: Use this if users have a "phoneNumber" field (most common structure)
            reference.orderByChild("phoneNumber").equalTo(phoneNum).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if(dataSnapshot.exists()){
                        // User exists: proceed to send OTP
                        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                                phoneNum,
                                60,
                                TimeUnit.SECONDS,
                                TaskExecutors.MAIN_THREAD,
                                mCallbacks);
                        Toast.makeText(context, "OTP sent to "+phoneNum, Toast.LENGTH_SHORT).show();
                        verifyOtpAndLogin.setVisibility(View.VISIBLE);
                        errorMessage.setVisibility(View.GONE);
                    }else{
                        // User doesn't exist: show error
                        errorMessage.setText("This phone number is not registered with us");
                        errorMessage.setVisibility(View.VISIBLE);
                        verifyOtpAndLogin.setVisibility(View.GONE);
                    }
                }
    
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Toast.makeText(context, "Database error: "+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
    
            // Option 2: Use this if phone number is the direct key of user nodes
            // reference.child(phoneNum).addListenerForSingleValueEvent(new ValueEventListener() {
            //     @Override
            //     public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            //         if(dataSnapshot.exists()){
            //             // Send OTP logic here
            //         }else{
            //             // Show error message
            //         }
            //     }
    
            //     @Override
            //     public void onCancelled(@NonNull DatabaseError databaseError) {
            //         Toast.makeText(context, "Database error: "+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
            //     }
            // });
        }
    }
    

Important Notes

  • Match Your Database Structure: Pick either Option 1 or 2 based on how you store user data:
    • Option 1 works if users are stored under a users node with a phoneNumber field (e.g., users/{userId}/phoneNumber: "+91xxxxxxxxx").
    • Option 2 works if you use the full phone number (with country code) as the user node key (e.g., users/+91xxxxxxxxx).
  • Security Tip: While this frontend check blocks most invalid requests, add a backend check with Firebase Cloud Functions to ensure no unauthorized users can bypass this restriction.

Full Modified Code

Here's the complete updated LoginActivity class with all changes included:

package com.lalbhaibrokers.lalbhaibrokerspvtltd;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.TaskExecutors;
import com.google.android.material.textfield.TextInputEditText;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.concurrent.TimeUnit;

public class LoginActivity extends AppCompatActivity {
    //Variables
    TextInputEditText mobileNumber, otp;
    TextView errorMessage, sendOtp, verifyOtpAndLogin;
    Context context = this;
    String verificationCode;
    boolean isVerified;
    FirebaseDatabase database;
    DatabaseReference reference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        //Hooks
        mobileNumber = findViewById(R.id.mobile_no_editText);
        otp = findViewById(R.id.otp_editText);
        errorMessage = findViewById(R.id.error_message_textView);
        sendOtp = findViewById(R.id.send_otp_btn);
        verifyOtpAndLogin = findViewById(R.id.verify_otp_and_login);

        // Initialize Firebase Database reference
        database = FirebaseDatabase.getInstance();
        reference = database.getReference("users");

        verifyOtpAndLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String userCode = otp.getText().toString();
                if (!userCode.isEmpty()) {
                    verifyCode(userCode); //verifying the code Entered by user
                }
            }
        });
    }

    //method for start the OTP process
    public void sendOtp(View view){
        if(mobileNumber.getText().toString().equals("")){
            errorMessage.setText("Please Enter phone number");
            errorMessage.setVisibility(View.VISIBLE);
        }else if(mobileNumber.getText().toString().length() != 10){
            errorMessage.setText("PhoneNumber is Invalid"); //we can only accept phoneNumbers with 10 digits
            errorMessage.setVisibility(View.VISIBLE);
        }else{
            final String phoneNum= "+91"+mobileNumber.getText().toString(); //we have to add country code in order to receive OTP
            
            // Check if user exists in database before sending OTP
            reference.orderByChild("phoneNumber").equalTo(phoneNum).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if(dataSnapshot.exists()){
                        // User exists: send OTP
                        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                                phoneNum, // Phone number to verify
                                60, // Timeout duration
                                TimeUnit.SECONDS, // Unit of timeout
                                TaskExecutors.MAIN_THREAD, // Activity (for callback binding)
                                mCallbacks); // OnVerificationStateChangedCallbacks
                        Toast.makeText(context, "OTP sent to "+phoneNum, Toast.LENGTH_SHORT).show();
                        verifyOtpAndLogin.setVisibility(View.VISIBLE);
                        errorMessage.setVisibility(View.GONE);
                    }else{
                        // User doesn't exist: show error
                        errorMessage.setText("This phone number is not registered with us");
                        errorMessage.setVisibility(View.VISIBLE);
                        verifyOtpAndLogin.setVisibility(View.GONE);
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Toast.makeText(context, "Database error: "+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    //method that verify the OTP received or not
    private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        @Override
        public void onCodeSent(@NonNull String s, @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
            super.onCodeSent(s, forceResendingToken);
            verificationCode = s; //verification code that should be received by phoneNumber
        }

        @Override
        public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
            String code = phoneAuthCredential.getSmsCode(); //verification code that actually received by phoneNumber
            if (code != null) {
                verifyCode(code);
            }
        }

        @Override
        public void onVerificationFailed(@NonNull FirebaseException e) {
            Toast.makeText(context, "Verification Failed: OTP not received", Toast.LENGTH_SHORT).show();
        }
    };

    //verifying the OTP
    public void verifyCode(String code) {
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationCode, code); //comparing both verification code
        signin(credential);
    }

    //signing in the User to update in database
    private void signin(PhoneAuthCredential credential) {
        FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
        firebaseAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Toast.makeText(context, "Verification Complete", Toast.LENGTH_SHORT).show();
                    isVerified=true;
                    Intent intent = new Intent(context, UserDashboard.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(context, "Verification Failed: OTP wrong", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

内容的提问来源于stack exchange,提问作者Hardik Trivedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:42:33