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

如何在Firebase Login Activity生成OTP前检查手机号是否已注册,未注册则跳转Signup Activity?

Hey there! Let's walk through how to implement this check before sending the OTP in your Firebase Login Activity. I'll cover two common approaches, depending on your security needs.

Approach 1: Check via Firestore (Client-Side, Simple & Fast)

Firebase Auth doesn't have a direct client API to check registered phone numbers, so we'll store each user's phone number in Firestore when they sign up, then query that collection during login.

Step 1: Store Phone Numbers During Signup

After a user successfully signs up and verifies their OTP, save their phone number to a Firestore users collection. Make sure the format matches what users will input in the login screen (e.g., include country code like +1234567890):

// Assuming you've already created the FirebaseUser after OTP verification
val db = FirebaseFirestore.getInstance()
val userProfile = hashMapOf(
    "phoneNumber" to firebaseUser.phoneNumber,
    "uid" to firebaseUser.uid
)
// Save to Firestore using the user's UID as the document ID
db.collection("users").document(firebaseUser.uid).set(userProfile)

Don't forget to lock down your Firestore security rules to prevent unauthorized access:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read: if request.auth != null; // Only authenticated users can read
      allow write: if request.auth.uid == userId; // Only the user can update their own data
    }
  }
}

Step 2: Check the Phone Number in Login Activity

When the user taps "Get OTP", first query Firestore to see if the number exists:

val inputPhone = phoneInputEditText.text.toString().trim()
val db = FirebaseFirestore.getInstance()

// Query for any user with the input phone number
db.collection("users")
    .whereEqualTo("phoneNumber", inputPhone)
    .get()
    .addOnSuccessListener { snapshot ->
        if (snapshot.isEmpty) {
            // No matching user found — send to Signup Activity
            startActivity(Intent(this@LoginActivity, SignupActivity::class.java))
            finish() // Optional: Prevent users from navigating back to login
        } else {
            // Number is registered — proceed with OTP generation
            sendOTP(inputPhone)
        }
    }
    .addOnFailureListener { error ->
        // Handle network errors or query failures
        Toast.makeText(this, "Failed to check number: ${error.message}", Toast.LENGTH_SHORT).show()
    }

Pro tip: Use a library like libphonenumber-android to standardize phone number formats (e.g., auto-add country codes, remove spaces) so your queries always match the stored values.

Approach 2: Check via Cloud Function (Server-Side, More Secure)

For stricter security (to prevent clients from tampering with query logic), use a Cloud Function that calls Firebase Admin SDK's getUserByPhoneNumber method.

Step 1: Write the Cloud Function

Initialize Cloud Functions in your project, then create an HTTPS callable function:

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

exports.checkPhoneRegistered = functions.https.onCall(async (data, context) => {
    const phoneNumber = data.phoneNumber;
    try {
        // Admin SDK will throw an error if the number isn't registered
        await admin.auth().getUserByPhoneNumber(phoneNumber);
        return { isRegistered: true };
    } catch (err) {
        if (err.code === "auth/user-not-found") {
            return { isRegistered: false };
        }
        // Re-throw other errors to notify the client
        throw new functions.https.HttpsError("internal", "Error verifying number", err);
    }
});

Deploy it with: firebase deploy --only functions

Step 2: Call the Function from Login Activity

Invoke the cloud function to check the phone number before sending OTP:

val inputPhone = phoneInputEditText.text.toString().trim()
val functions = FirebaseFunctions.getInstance()

functions.getHttpsCallable("checkPhoneRegistered")
    .call(hashMapOf("phoneNumber" to inputPhone))
    .addOnSuccessListener { result ->
        val isRegistered = result.data as Boolean
        if (!isRegistered) {
            startActivity(Intent(this@LoginActivity, SignupActivity::class.java))
            finish()
        } else {
            sendOTP(inputPhone)
        }
    }
    .addOnFailureListener { error ->
        Toast.makeText(this, "Check failed: ${error.message}", Toast.LENGTH_SHORT).show()
    }

This method is more secure because the verification happens server-side, so clients can't bypass the check.

Key Notes
  • Format Consistency: Always use the same phone number format (e.g., with country code, no special characters) across signup and login.
  • Error Handling: Don't skip error handling — network drops or Firebase issues can happen, so give users clear feedback.
  • Privacy Compliance: Make sure you're allowed to store user phone numbers under your region's privacy laws (like GDPR).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:25:07