如何用Firebase在注册/登录时向邮箱、手机号发OTP及无密码注册验证规则
Hey there! Let’s walk through how to build a passwordless OTP-based registration and login flow for your social media app using Firebase, plus the key validation rules for emails and phone numbers you’ll need to follow.
Before writing any code, head to your Firebase Console > Authentication > Sign-in method and enable two core methods:
- Email link (passwordless sign-in) (under the Email/Password section)
- Phone
Don’t forget to add your app’s domain to the Authorized domains list to avoid CORS or redirect issues.
Firebase supports both magic links and numeric OTPs for email-based passwordless auth. Here’s how to implement the OTP flow:
Step 1: Send OTP to the User’s Email
In your frontend code (e.g., JavaScript), trigger the OTP email with this snippet:
const actionCodeSettings = { url: "https://your-app.com/verify-otp", // Your app's redirect URL post-verification handleCodeInApp: true, // Required for OTP flow iOS: { bundleId: "com.your-app.ios" }, android: { packageName: "com.your-app.android", minimumVersion: "12" } }; firebase.auth().sendSignInLinkToEmail(userEmail, actionCodeSettings) .then(() => { // Store the email locally to verify later window.localStorage.setItem('emailForSignIn', userEmail); alert("OTP sent to your email—check your inbox!"); }) .catch((error) => { console.error(error); alert(`Oops: ${error.message}`); });
Step 2: Verify the OTP/Link
When the user clicks the email link or enters the numeric OTP, confirm their identity:
const storedEmail = window.localStorage.getItem('emailForSignIn'); if (firebase.auth().isSignInWithEmailLink(window.location.href)) { firebase.auth().signInWithEmailLink(storedEmail, window.location.href) .then((result) => { // Clear stored email and proceed window.localStorage.removeItem('emailForSignIn'); console.log("User registered/logged in:", result.user); // Redirect to your app's main screen here }) .catch((error) => { console.error("Verification failed:", error); alert("Invalid or expired link—request a new OTP!"); }); }
Email Validation Rules
- Format Check: Enforce a valid email pattern (e.g.,
user@domain.tld) with a frontend regex like^[^\s@]+@[^\s@]+\.[^\s@]+$—Firebase does basic checks, but catching errors early improves UX. - Deliverability: Block temporary/disposable emails (use a third-party API in a Firebase Cloud Function to flag these, since Firebase doesn’t block them by default).
- Uniqueness: Firebase automatically ensures each email is linked to only one account, so you don’t need to handle duplicate registrations manually.
Phone-based OTP requires reCAPTCHA to prevent bot abuse. Here’s the step-by-step implementation:
Step 1: Set Up Invisible ReCAPTCHA
Add a container to your frontend:
<div id="recaptcha-container"></div>
Initialize it in your code:
const recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', { size: 'invisible', callback: () => { /* reCAPTCHA solved, proceed */ } });
Step 2: Send OTP to the Phone Number
Critical: The phone number must follow the E.164 standard (e.g., +1234567890—no spaces, parentheses, or hyphens):
const phoneNumber = "+1234567890"; // Get from user input, enforce E.164 format firebase.auth().signInWithPhoneNumber(phoneNumber, recaptchaVerifier) .then((confirmationResult) => { // Store confirmation result globally to use for OTP verification window.confirmationResult = confirmationResult; alert("OTP sent to your phone!"); }) .catch((error) => { console.error("Failed to send OTP:", error); // Reset reCAPTCHA if needed recaptchaVerifier.render().then((widgetId) => grecaptcha.reset(widgetId)); });
Step 3: Verify the OTP
When the user enters the 6-digit code, confirm it:
const otpCode = document.getElementById('otp-input').value; window.confirmationResult.confirm(otpCode) .then((result) => { const user = result.user; console.log("User registered/logged in:", user); // Redirect to main app screen }) .catch((error) => { console.error("Invalid OTP:", error); alert("Wrong code—try again or request a new OTP."); });
Phone Number Validation Rules
- E.164 Format: Non-negotiable—Firebase rejects numbers without a valid country code or invalid formatting. Add frontend logic to auto-prepend the user’s country code and strip special characters.
- Validity: Block virtual/VOIP numbers if your app requires real mobile lines. Firebase flags some automatically, but use a phone validation API in a Cloud Function for stricter checks.
- Uniqueness: Firebase ensures each phone number is linked to only one auth account.
You don’t need separate sign-up and sign-in flows! Firebase treats the first OTP verification as registration, and subsequent attempts as login. Just let users enter their email or phone, send the OTP, and verify it—Firebase handles the rest.
- OTP Expiry: Firebase OTPs expire after 5 minutes. Add logic to prompt users to resend if verification fails due to expiration.
- Rate Limits: Firebase blocks excessive OTP requests. Handle the
auth/too-many-requestserror by telling users to try again in 10-15 minutes. - Account Linking: If a user signs in with both email and phone, link the methods using
user.linkWithCredential()to keep their account unified. - Post-Registration Checks: Use Firebase Cloud Functions to run custom validations (e.g., verifying email domain, blocking banned phone numbers) and disable non-compliant accounts.
内容的提问来源于stack exchange,提问作者AL OK

