Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by VoidCollector403

Firebase Phone Authentication in React Fails for Real Numbers with an 'Invalid Application Verifier' Error

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I'm implementing Firebase Phone Authentication in my React app, and while test numbers work perfectly, real phone numbers trigger a reCAPTCHA and then fail with an error. Here’s the situation:

  • Testing Setup:

    • I added my Sim 1 number in the Firebase Console under "Phone Authentication" as a test number.
    • This number works as expected: inputting it shows an "OTP sent" alert, and using the predefined OTP creates the user successfully.
  • Real-world Testing:

    • I use my Sim 2 number, which is not listed as a test number, to simulate a real user.
    • After entering the number, the reCAPTCHA appears and works correctly, but instead of receiving an OTP alert, I get the error:
JAVASCRIPT
The phone verification request contains an invalid application verifier. The reCAPTCHA token response is either invalid or expired.

Below is my Firebase configuration and React component code used for authentication:

Firebase Configuration

JAVASCRIPT
import firebase from 'firebase'; import "firebase/auth"; // For Firebase JS SDK v7.20.0 and later, measurementId is optional const firebaseConfig = { apiKey: "xxxxxxxxxxxxx", authDomain: "xxxxxxxxxx", projectId: "xxxxxxxxx", storageBucket: "xxxxxxxxxx", messagingSenderId: "xxxxxxxxxxxx", appId: "xxxxxxxxxxxxxx", measurementId: "xxxxxxxxxxxxx" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); const projectStorage = firebase.storage(); const projectFirestore = firebase.firestore(); const timestamp = firebase.firestore.FieldValue.serverTimestamp(); const auth = firebase.auth(); const provider = new firebase.auth.GoogleAuthProvider(); const increment = firebase.firestore.FieldValue.increment(1); export { projectStorage, projectFirestore, timestamp, auth, provider, increment, firebase };

React Component

JAVASCRIPT
import React, { useState } from "react"; import firebase from "firebase"; // Import the Firebase config const PhoneAuth = () => { const [phoneNumber, setPhoneNumber] = useState(""); const [otp, setOtp] = useState(""); const [verificationId, setVerificationId] = useState(""); // Initialize reCAPTCHA const initializeRecaptcha = () => { window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier("recaptcha-container", { size: "normal", callback: (response) => { console.log("reCAPTCHA solved:", response); }, "expired-callback": () => { console.error("reCAPTCHA expired. Please try again."); }, }); window.recaptchaVerifier.render().then((widgetId) => { console.log("reCAPTCHA rendered with widget ID:", widgetId); }); }; // Send OTP const handleSendCode = () => { initializeRecaptcha(); // Reinitialize reCAPTCHA every time const appVerifier = window.recaptchaVerifier; firebase .auth() .signInWithPhoneNumber(phoneNumber, appVerifier) .then((confirmationResult) => { setVerificationId(confirmationResult.verificationId); alert("OTP sent!"); }) .catch((error) => { console.error("Error during phone auth:", error); alert(error.message); }); }; // Verify OTP const handleVerifyCode = () => { const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, otp); firebase .auth() .signInWithCredential(credential) .then(() => { alert("Phone number verified successfully!"); }) .catch((error) => { console.error("Error verifying OTP:", error); alert(error.message); }); }; return ( <div className="phone-auth"> <h2>Phone Authentication</h2> <div id="recaptcha-container"></div> <input type="text" placeholder="Enter phone number (+1234567890)" value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} /> <button onClick={handleSendCode}>Send OTP</button> <input type="text" placeholder="Enter OTP" value={otp} onChange={(e) => setOtp(e.target.value)} /> <button onClick={handleVerifyCode}>Verify OTP</button> </div> ); }; export default PhoneAuth;

What I've Tried

  1. Verified that Firebase Phone Authentication is enabled in the Firebase Console.
  2. Added the app domain (e.g., localhost during development) to the Authorized Domains.
  3. Noted that the reCAPTCHA appears and functions for test numbers but fails for real numbers.

My Question
Why does the error "The phone verification request contains an invalid application verifier. The reCAPTCHA token response is either invalid or expired." occur for non-test numbers, and how can I resolve this issue?

0

Comments 0

Answers 2

Views 55

2 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

Below is an explanation of what’s happening and how to resolve it.


Why It Happens

When you test with numbers registered as test numbers, Firebase bypasses the reCAPTCHA verification step. However, for real phone numbers Firebase requires a valid, current reCAPTCHA token. The error

  "The phone verification request contains an invalid application verifier. The reCAPTCHA token response is either invalid or expired."

indicates that the verifier (the reCAPTCHA token) is not valid at the time the sign-in request is made. This can occur if:

• The reCAPTCHA is being reinitialized unnecessarily so that its token is reset or expires before you use it.

• There is a delay between solving the reCAPTCHA and calling signInWithPhoneNumber, which can lead to token expiration.

• The reCAPTCHA instance isn’t set up correctly (for example, reusing an already rendered instance or not waiting for it to be ready).


How to Fix It

  1. Initialize reCAPTCHA Only Once
    Instead of reinitializing the reCAPTCHA every time you click “Send OTP,” initialize it separately (for example, when the component mounts) so that you always have a valid verifier. You can do this in a useEffect hook.

  2. Use the Correct Widget Instance
    Make sure you are rendering the reCAPTCHA once, capturing its widgetId, and then using that same verifier for your sign-in request.

  3. Ensure Timely Use of the Token
    After the user solves the reCAPTCHA, use the phone number immediately for sending the OTP so that the reCAPTCHA token is not expired.


Sample Code Update

Below is an updated version of your component that initializes the reCAPTCHA only once on component mount. This helps ensure that you always have a valid application verifier when you call signInWithPhoneNumber.

JAVASCRIPT
import React, { useState, useEffect } from "react"; import firebase from "firebase"; const PhoneAuth = () => { const [phoneNumber, setPhoneNumber] = useState(""); const [otp, setOtp] = useState(""); const [verificationId, setVerificationId] = useState(""); const [isRecaptchaInitialized, setIsRecaptchaInitialized] = useState(false); useEffect(() => { // Initialize reCAPTCHA only once when component mounts if (!isRecaptchaInitialized) { window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier( "recaptcha-container", { size: "normal", callback: (response) => { console.log("reCAPTCHA solved:", response); }, "expired-callback": () => { console.error("reCAPTCHA expired. Please try again."); }, } ); window.recaptchaVerifier.render().then((widgetId) => { console.log("reCAPTCHA rendered with widget ID:", widgetId); }); setIsRecaptchaInitialized(true); } }, [isRecaptchaInitialized]); // Send OTP const handleSendCode = () => { const appVerifier = window.recaptchaVerifier; firebase .auth() .signInWithPhoneNumber(phoneNumber, appVerifier) .then((confirmationResult) => { setVerificationId(confirmationResult.verificationId); alert("OTP sent!"); }) .catch((error) => { console.error("Error during phone auth:", error); alert(error.message); }); }; // Verify OTP const handleVerifyCode = () => { const credential = firebase.auth.PhoneAuthProvider.credential(verificationId, otp); firebase .auth() .signInWithCredential(credential) .then(() => { alert("Phone number verified successfully!"); }) .catch((error) => { console.error("Error verifying OTP:", error); alert(error.message); }); }; return ( <div className="phone-auth"> <h2>Phone Authentication</h2> <div id="recaptcha-container"></div> <input type="text" placeholder="Enter phone number (+1234567890)" value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} /> <button onClick={handleSendCode}>Send OTP</button> <input type="text" placeholder="Enter OTP" value={otp} onChange={(e) => setOtp(e.target.value)} /> <button onClick={handleVerifyCode}>Verify OTP</button> </div> ); }; export default PhoneAuth;

Summary

The error for non-test numbers occurs because a valid and current reCAPTCHA token is required for real SMS authentication. By initializing the reCAPTCHA only once (for example, on component mount), and ensuring that you use it promptly (before it expires), you can fix the issue. Additionally, avoid reinitializing the verifier on every request.

This should resolve the issue and allow real phone numbers to authenticate correctly.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by NebularSentinel087 1 month ago

0

The error you're encountering, "The phone verification request contains an invalid application verifier," can sometimes occur due to invalid or unsupported phone numbers. I ran into a similar issue while working on phone number authentication with Firebase, and I found that this error often happens when numbers aren’t fully validated or don’t meet the required standards.

One trick that worked wonders for me was ensuring the phone numbers I was using were properly validated before sending them to Firebase. I started checking the numbers for proper formatting (like E.164 format) and making sure they were actually mobile numbers. I used a phone number validation tool Landline remover that helped me filter out landlines and VoIP numbers, which don’t work well with Firebase authentication.

By adding this validation step, I reduced the number of reCAPTCHA token issues significantly. The numbers that went through were always the right ones, making the process smoother and more reliable.

you should try phone number validation tool " https://landlineremover.com/api/ "may that help you!

No comments yet.

Discussion

No comments yet.