Skip to content

Firebase phoneauth with nextjs - phone verification request contains an invalid application verifier, reCAPTCHA token is either invalid or expired. #6383

Description

@rohitgurudasani

signInWithPhoneNumber throwing below error randomly after manually verifying CAPTCHA on production environment.
note:- working fine on localhost.

npm package:-
firebase version:- "9.8.3"
next: "12.0.7",

Error :-

error msg:- The phone verification request contains an invalid application verifier. The reCAPTCHA token response is either invalid or expired.

"error": {
    "code": 400,
    "message": "INVALID_APP_CREDENTIAL",
   }

Reproducible Example: -

// firebase.config.ts

import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';
import 'firebase/compat/app-check';
import 'firebase/compat/storage';


let app: firebase.app.App;

if (!firebase.apps.length) {
  app = firebase.initializeApp({
    apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
    authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
    messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGE_SENDER_ID,
    appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
    storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  });
} else {
  app = firebase.app();
}

if (typeof window !== 'undefined') {
  const appCheck = firebase.appCheck();
  appCheck.activate(process.env.NEXT_PUBLIC_FIREBASE_APP_CHECK_SITE_KEY!, true);
}
export const auth = app.auth();
export const firestore = app.firestore();
export const storage = app.storage();
export { firebase };
export default app;
// login.tsx

import { auth, firebase } from './firebase.config.ts';

export default function LoginDialog(props: any) {
  const signin = async () => {
    if (auth.currentUser) {
      localStorage.clear();
      auth.signOut();
    }

    try {
      setLoading(true);
      setKeyStr(keyStr + Math.random());
      const recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
        size: 'invisible',
      });
      const response = await auth.signInWithPhoneNumber('+91' + phoneNumber, recaptchaVerifier);

      setAuthContext(response);
      setIsOtpSent(true);
      setShowCaptcha(true);
      setLoading(false);
      return response;
    } catch (error) {
      setShowCaptcha(false);
      setRequestError(error?.message);
      setLoading(false);
    }
  };

  return (
    <>
      <LoadingButton
        color="primary"
        variant="contained"
        size="large"
        loading={loading}
        onClick={signin}
        disabled={disableButton}
        fullWidth
      >
        {'GET OTP'}
      </LoadingButton>

      <div id="sign-in-button" key={showCaptcha}></div>
    </>
  );
}


Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions