Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

OTP Not Received When Using signInWithPhoneNumber on Cloud Server #8610

Open
oardilac opened this issue Oct 26, 2024 · 5 comments
Open

OTP Not Received When Using signInWithPhoneNumber on Cloud Server #8610

oardilac opened this issue Oct 26, 2024 · 5 comments

Comments

@oardilac
Copy link

Operating System

Linux Ubuntu

Environment (if applicable)

Vercel

Firebase SDK Version

11.0.1

Firebase SDK Product(s)

Auth, Messaging

Project Tooling

  • Next.js
  • TypeScript

Detailed Problem Description

  • The signInWithPhoneNumber function works seamlessly in the local development environment but fails to deliver the OTP when deployed on the cloud.
  • The phone numbers used are valid Colombian numbers, and the formatting adheres to Firebase's requirements.
  • Recaptcha is set to invisible, and its initialization appears correct in both environments.
  • No network restrictions or firewall rules are preventing OTP delivery from the cloud server.
  • The issue might be related to Firebase's backend services when handling requests from the cloud server environment.

Steps and code to reproduce issue

1. Create a Minimal Next.js Application

Set up a new Next.js application (if you don't have one already):

npx create-next-app@latest firebase-otp-test
cd firebase-otp-test

2. Install Firebase Dependencies

Install Firebase SDK:

npm install firebase

3. Configure Firebase

Create a firebase.ts file in the services directory to initialize Firebase:

// services/firebase.ts

import { initializeApp } from "firebase/app";
import {
  getAuth,
  signInWithPhoneNumber,
  RecaptchaVerifier,
} from "firebase/auth";

const firebaseConfig = {
  apiKey: "YOUR_API_KEY", // Replace with your Firebase config
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_SENDER_ID",
  appId: "YOUR_APP_ID",
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

export { auth, signInWithPhoneNumber, RecaptchaVerifier };

⚠️ Important: Replace the placeholder values in firebaseConfig with your actual Firebase project credentials._

4. Implement the OTP Login Component

Create a simple OTP login component using Firebase's signInWithPhoneNumber:

// pages/#.tsx

"use client";

import { useState, useEffect } from "react";
import { auth, signInWithPhoneNumber, RecaptchaVerifier } from "@/services/firebase";

export default function Login() {
  const [phoneNumber, setPhoneNumber] = useState("");
  const [otp, setOtp] = useState("");
  const [confirmationResult, setConfirmationResult] = useState<any>(null);
  const [message, setMessage] = useState("");

  useEffect(() => {
    // Initialize reCAPTCHA verifier
    const verifier = new RecaptchaVerifier("recaptcha-container", {
      size: "invisible",
      callback: (response: any) => {
        // reCAPTCHA solved, allow signInWithPhoneNumber.
        console.log("reCAPTCHA solved");
      },
    }, auth);
    verifier.render();
  }, []);

  const requestOTP = async () => {
    try {
      const confirmation = await signInWithPhoneNumber(auth, phoneNumber, new RecaptchaVerifier('recaptcha-container', {}, auth));
      setConfirmationResult(confirmation);
      setMessage("OTP has been sent to your phone.");
    } catch (error: any) {
      console.error("Error sending OTP:", error);
      setMessage(`Error: ${error.message}`);
    }
  };

  const verifyOTP = async () => {
    try {
      await confirmationResult.confirm(otp);
      setMessage("Phone number verified successfully!");
    } catch (error: any) {
      console.error("Error verifying OTP:", error);
      setMessage(`Error: ${error.message}`);
    }
  };

  return (
    <div className="flex flex-col items-center justify-center min-h-screen">
      <h1>Login with Phone Number</h1>
      <input
        type="tel"
        placeholder="Enter phone number"
        value={phoneNumber}
        onChange={(e) => setPhoneNumber(e.target.value)}
        className="border p-2 m-2"
      />
      {!confirmationResult && (
        <button onClick={requestOTP} className="bg-blue-500 text-white p-2 m-2">
          Send OTP
        </button>
      )}
      {confirmationResult && (
        <>
          <input
            type="text"
            placeholder="Enter OTP"
            value={otp}
            onChange={(e) => setOtp(e.target.value)}
            className="border p-2 m-2"
          />
          <button onClick={verifyOTP} className="bg-green-500 text-white p-2 m-2">
            Verify OTP
          </button>
        </>
      )}
      <div id="recaptcha-container"></div>
      {message && <p className="mt-4">{message}</p>}
    </div>
  );
}

5. Test Locally

  1. Run the Application Locally:

    npm run dev
  2. Access the Login Page:

    • Navigate to http://localhost:3000/#.
    • Enter a valid phone number and request an OTP.
    • Verify that the OTP is received on the specified phone number and that verification succeeds.

6. Deploy to Cloud Server

  1. Choose a Hosting Platform:
    • For example, deploy to Vercel:

      npm install -g vercel
      vercel
@oardilac oardilac added new A new issue that hasn't be categoirzed as question, bug or feature request question labels Oct 26, 2024
@google-oss-bot
Copy link
Contributor

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@jbalidiong jbalidiong added api: auth needs-attention and removed needs-triage new A new issue that hasn't be categoirzed as question, bug or feature request labels Oct 28, 2024
@moderniselife
Copy link

moderniselife commented Nov 6, 2024

We are having this same issue, however it doesn't work locally either.

We upgraded from 10.14.0 (the last version that works) to 11.0.1 (we also tried 10.14.1 and that only worked for a day and half) and MFA broke completely. It no longer provides the error.resolve and just returns undefined in the catch error instead.

We are using the namespaced/compat variant, however that shouldn't matter due to the way the compat version is configured in the SDK codebase.

Has there been any progress into this?

Update

Further investigation has lead to a potential recaptcha issue in where the api.js isn't being loaded causing it not to load the recaptchaParams config, which then leads to it not being able to call the reload for the recaptcha key and thus finally not allowing MFA token not to be sent.

We are still investigating and trying to find a fix / workaround. I will keep this ticket updated.

We have also noticed around the midnight rollover for the USA (to Sydney time) is when it seems to start to break for 10.14.1

@NhienLam
Copy link
Contributor

NhienLam commented Nov 12, 2024

Hi @oardila, thanks for filing the issue. I've tried reproducing the issue with an app deployed to Firebase Hosting, but the SMS OTP code is sent successfully (v11.0.1 modular).

  1. Did you receive any errors?
  2. Does the issue occur when using older SDK versions?
  3. Make sure that the region the you want to enable is added to the Allow list in Authentication settings > SMS region policy.

If you think this isn't an SDK bug, I would suggest contacting Firebase Support so that backend team can debug the issue.

Edit

I noticed you are initializing RecaptchaVerifier twice (one invisilbe and one visible). Is that intended? Could you try reusing the existing RecaptchaVerifier when calling signInWithPhoneNumber?

@NhienLam
Copy link
Contributor

Hi @moderniselife, thanks for sharing your problem. I've tried reproducing the issue with v11.0.1 compat libraries both locally and with an app deployed to Firebase Hosting, but the SMS OTP was sent successfully in both cases.

In the network log, do you see the API call (mfaEnrollment:start or mfaSignIn:start) or any errors?

Further investigation has lead to a potential recaptcha issue in where the api.js isn't being loaded causing it not to load the recaptchaParams config

Could you please elaborate on how you know the recaptcha api.js script is not loading?

We upgraded from 10.14.0 (the last version that works) to 11.0.1 (we also tried 10.14.1 and that only worked for a day and half) and MFA broke completely.

The fact that it's working on 10.14.0 and started breaking in 10.14.1 suggests that this is an SDK issue. However, if it were truly an SDK issue, it should consistently fail in 10.14.1, not work intermittently as you described. While we made changes to the phone auth flows in 11.0.0, I don't believe those changes are the cause, as the issue appeared in 10.14.1.

@moderniselife
Copy link

@NhienLam here are our HAR logs.

There seems to be around 23 Recaptcha Requests and 2 MFA requests missing from the HAR file labelled Broken.

The broken (v11.0.1) does not contain either of the mfa ones, and the expected (v10.14.0) has the mfaSignIn:start.
HARs.zip

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

5 participants