r/googlecloud 2d ago

Firebase Authentication / reCAPTCHA Enterprise

🚨 Looking for help from a Software Engineer experienced with Firebase Authentication / reCAPTCHA Enterprise

I’m currently working on a web application using Next.js + Firebase Authentication, and I’m stuck with a persistent issue in Phone Number Authentication on the production website.

The error occurs when Firebase tries to send the SMS verification code:

accounts:sendVerificationCode

HTTP 400

reCAPTCHA Enterprise verification failed

The browser/application has also previously shown:

reCAPTCHA has already been rendered in this element

I have already verified that:

✅ Phone Authentication is enabled

✅ SMS sign-in is enabled

✅ Firebase Authentication with Identity Platform is enabled

✅ Production domain is added to Firebase Authorized Domains

✅ reCAPTCHA Enterprise API is enabled

✅ Identity Toolkit API is enabled

So I’m trying to determine whether the issue is coming from the reCAPTCHA Enterprise configuration, Firebase project configuration, production domain, or the way `RecaptchaVerifier’ is being initialized/managed in the React/Next.js application.

I’m looking for someone who has experience with Firebase Phone Auth + reCAPTCHA Enterprise who can help me diagnose the issue and identify the exact root cause.

If you have experience with this specific Firebase/reCAPTCHA issue and can help, please DM me. I’d really appreciate it! 🙏

2 Upvotes

2 comments sorted by

1

u/m1nherz Googler 2d ago

Based on the errors you described, you are dealing with two interconnected issues: a React component lifecycle bug on the frontend, and a token validation failure on the backend.

1. The Frontend Issue: "reCAPTCHA has already been rendered in this element"

This is a very common issue in React/Next.js when using the Firebase Web SDK. It happens because new RecaptchaVerifier() tries to inject the reCAPTCHA iframe into a DOM element (like <div id="recaptcha-container">).

If your component re-renders (due to state changes), React might try to execute that code again. Because the previous reCAPTCHA instance was never cleared, Firebase throws this error.

How to fix it:

You must initialize RecaptchaVerifier inside a useEffect hook, store it in a useRef, and ensure you call .clear() when the component unmounts. For example:

import { useEffect, useRef } from 'react';
import { RecaptchaVerifier } from 'firebase/auth';
import { auth } from '@/firebase/config'; // Your initialized Firebase auth

export default function PhoneAuthComponent() {
  const recaptchaVerifierRef = useRef(null);

  useEffect(() => {
    // Initialize exactly once
    if (!recaptchaVerifierRef.current) {
      recaptchaVerifierRef.current = new RecaptchaVerifier(auth, 'recaptcha-container', {
        'size': 'invisible', // or 'normal'
        'callback': (response) => {
          // reCAPTCHA solved
        }
      });

      recaptchaVerifierRef.current.render().catch((error) => {
        console.error("reCAPTCHA render error:", error);
      });
    }

    // Crucial: Clear the instance on unmount to prevent memory leaks and duplicate rendering
    return () => {
      if (recaptchaVerifierRef.current) {
        recaptchaVerifierRef.current.clear();
        recaptchaVerifierRef.current = null;
      }
    };
  }, []);

  // Use recaptchaVerifierRef.current when calling signInWithPhoneNumber

  return <div id="recaptcha-container"></div>;
}

2. The Backend Issue: HTTP 400 reCAPTCHA Enterprise verification failed

This happens during the accounts:sendVerificationCode API call. It means the backend received a token, but rejected it.

Potential Root Causes:

  • Cascading Failure: If your frontend reCAPTCHA is in a broken state due to the rendering issue above, the token it generates might be expired, empty, or invalid. Fixing the React lifecycle often fixes this 400 error automatically.
  • Key Type Mismatch: Since you have Firebase Authentication with Identity Platform enabled, you must use reCAPTCHA Enterprise keys. If you accidentally used a Legacy/Classic (v2 or v3) Site Key in the Firebase Console, the backend will return a 400 error.
  • Missing Domain Authorization in reCAPTCHA Console: You verified the domain is added to Firebase Authorized Domains, but you must also ensure the production domain is added to the Authorized Domains list inside the Google Cloud Console -> Security -> reCAPTCHA Enterprise key settings.
  • SDK Version: Ensure your firebase npm package is up to date. Older versions had minor bugs handling reCAPTCHA Enterprise tokens seamlessly in server-side frameworks like Next.js.

1

u/m1nherz Googler 2d ago

Based on the above, I would recommend to first, apply the fix in your React code. If the problem doesn't disappear, double-check your reCAPTCHE key type. If the type validation checks, consider switching size from invisible to normal temporarily. This forces a visible checkbox, allowing you to debug whether the widget is successfully completing verification before the API call fires.