简体   繁体   English

错误:当通过 Firebase 在 ReactJs 中发送 OTP 时,reCAPTCHA 已在此元素中呈现

[英]Error: reCAPTCHA has already been rendered in this element, when sending OTP in ReactJs via Firebase

I'm using Firebase to send OTP on user mobile number, I'm implementing it into ReactJS. If first time I send OTP by clicking Button, it works fine, but if I click button more than 1 times without refreshing the page I get error "reCAPTCHA has already been rendered in this element".我正在使用 Firebase 在用户手机号码上发送 OTP,我正在将它实现到 ReactJS。如果我第一次通过单击按钮发送 OTP,它工作正常,但如果我单击按钮超过 1 次而不刷新页面我得到错误“reCAPTCHA 已在此元素中呈现”。

I'm not able to find proper solution for this.我无法为此找到合适的解决方案。 I tried many other solutions, found by googling but no one worked for me.我尝试了许多其他解决方案,通过谷歌搜索找到但没有人为我工作。 Your help/suggestions will be helpful for me.您的帮助/建议对我很有帮助。 Thank you.谢谢你。

Firebase Code for sending OTP:- Firebase 发送 OTP 的代码:-

var recaptchaVerifier = new RecaptchaVerifier(
      "recaptcha-container",
      {
        size: "invisible",
      },
      auth
    );

    recaptchaVerifier.render();
    signInWithPhoneNumber(auth, mobileNumber, recaptchaVerifier)
      .then((confirmationResult) => {
        setFirebaseOtpResult(confirmationResult);
        setShowModal(true);
      })
      .catch((error) => {
        addToast("Something went wrong, please try again", {
          appearance: "error",
          autoDismiss: true,
        });
        console.log("error", error);
      });
  };

Component Code:-组件代码:-

import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { useSelector } from "react-redux";
import PhoneInput from "react-phone-number-input";
import "react-phone-number-input/style.css";
import { auth } from "../utils/firebase";
import { RecaptchaVerifier, signInWithPhoneNumber } from "firebase/auth";
import { Modal } from "react-bootstrap";
import "./forgot_password.style.css";
import { useToasts } from "react-toast-notifications";
import { API } from "../utils/api";

const ForgotPassword = () => {
  const history = useHistory();
  const { addToast } = useToasts();
  const { setting } = useSelector((state) => state.layoutSetting);
  const style = {
    color: setting.web_font_color,
    fontVariant: setting.web_font_variant,
    fontStyle: setting.web_font_style,
    fontWeight: setting.web_font_weight,
  };
  const phoneNumberValue = "";
  const [otp, setOtp] = useState("");
  const [mobileNumber, setMobileNumber] = useState("");
  const [showModal, setShowModal] = useState(false);
  const [firebaseOtpResult, setFirebaseOtpResult] = useState("");
  const [userId, setUserId] = useState("");

  const submitHandler = async (e) => {
    e.preventDefault();

    const params = { mobilenumber: mobileNumber };
    const config = {
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    };
    const { data } = await API.post("/foroget_passworod", params, config);
    if (data.code !== "SUCCESS") {
      addToast(data.message, {
        appearance: "error",
        autoDismiss: true,
      });
      return;
    }

    var recaptchaVerifier = new RecaptchaVerifier(
      "recaptcha-container",
      {
        size: "invisible",
      },
      auth
    );

    recaptchaVerifier.render();
    signInWithPhoneNumber(auth, mobileNumber, recaptchaVerifier)
      .then((confirmationResult) => {
        setFirebaseOtpResult(confirmationResult);
        setShowModal(true);
      })
      .catch((error) => {
        addToast("Something went wrong, please try again", {
          appearance: "error",
          autoDismiss: true,
        });
        console.log("error", error);
      });
    setUserId(data.data.id);
  };

  const submitHandlerOTP = (e) => {
    e.preventDefault();
    if (!otp.trim().length) {
      addToast("Please enter OTP code", {
        appearance: "error",
        autoDismiss: true,
      });
      return;
    }
    firebaseOtpResult
      .confirm(otp)
      .then((result) => {
        addToast("OTP verified", {
          appearance: "success",
          autoDismiss: true,
        });
        localStorage.setItem("user_id", JSON.stringify(userId));
        history.push("/change-password");
      })
      .catch((error) => {
        addToast("Invalid OTP enterd", {
          appearance: "error",
          autoDismiss: true,
        });
      });
  };

  return (
    <>
      <div className="login-form-container">
        <div className="login-register-form">
          <form onSubmit={submitHandler}>
            <PhoneInput
              placeholder="Mobile Number"
              international={true}
              defaultCountry="PK"
              countryCallingCodeEditable={false}
              value={phoneNumberValue}
              required
              onChange={setMobileNumber}
            />
            <div id="recaptcha-container"></div>
            <div className="button-box">
              <button
                type="submit"
                style={{ ...style, background: setting.web_background_color }}
              >
                <span>Send OTP</span>
              </button>
            </div>
          </form>
        </div>
      </div>

      {/* OTP Modal */}
      <Modal show={showModal}>
        <Modal.Header> Verify OTP </Modal.Header>
        <Modal.Body>
          <div className="row">
            <div className="col-md-12">
              <div className="login-form-container">
                <div className="login-register-form">
                  <form onSubmit={submitHandlerOTP}>
                    <input
                      type="number"
                      placeholder="Please enter OPT sent to you"
                      required
                      onChange={(e) => setOtp(e.target.value)}
                    />
                    <div id="recaptcha-container"></div>
                    <div className="button-box" style={{ textAlign: "center" }}>
                      <button
                        type="submit"
                        style={{
                          ...style,
                          background: setting.web_background_color,
                          border: "none",
                          padding: "7px 30px",
                          marginTop: "25px",
                        }}
                      >
                        <span>Verify</span>
                      </button>
                      <button
                        type="button"
                        style={{
                          ...style,
                          background: setting.web_background_color,
                          border: "none",
                          padding: "7px 30px",
                          marginTop: "25px",
                          marginLeft: "10px",
                        }}
                        onClick={() => setShowModal(false)}
                      >
                        <span>Close</span>
                      </button>
                    </div>
                  </form>
                </div>
              </div>
            </div>
          </div>
        </Modal.Body>
      </Modal>
    </>
  );
};

export default ForgotPassword;

firebase.js firebase.js

import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

const config = {
    apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
    storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
    messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
    appId: process.env.REACT_APP_FIREBASE_APP_ID
};

const app = initializeApp(config);
export const auth = getAuth(app); 
export default app;

Issue resolved When I changed firebase code问题已解决当我更改 firebase 代码时

from:-从:-

var recaptchaVerifier = new RecaptchaVerifier(
   "recaptcha-container",
    {
     size: "invisible",
    },
      auth
);
recaptchaVerifier.render();

To:-到:-

if(!window.recaptchaVerifier){
      window.recaptchaVerifier = new RecaptchaVerifier(
        "recaptcha-container",
        {
          size: "invisible",
        },
        auth
      );
 }
window.recaptchaVerifier.render();

We don't need to create object of RecaptchaVerifier when an object already exists.当 object 已经存在时,我们不需要创建 RecaptchaVerifier 的 object。

I hope this may help future visitors,我希望这可以帮助未来的访客,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Firebase reCAPTCHA 已在此元素中呈现 - Firebase reCAPTCHA has already been rendered in this element Firebase 9 invisble recaptcha 元素抛出“reCAPTCHA 客户端元素已被删除”错误 - Firebase 9 invisble recaptcha element is throwing "reCAPTCHA client element has been removed" error Firebase 未向手机号码发送 OTP - Firebase is not sending OTP to the Mobile Number 无法使用 ReactJS 中的 firebase 身份验证重新发送 OTP - Not able to resend OTP using firebase auth in ReactJS “Firebase 错误:Firestore 已经启动,无法再更改其设置。” 将 Firebase v9 与 Firestore 模拟器连接 - "Firebase Error : Firestore has already been started and its settings can no longer be changed." connecting Firebase v9 with Firestore Emulator Azure Function OpenAPI - 已添加错误相同的密钥 - Azure Function OpenAPI - Error same key has already been added Firebase 电话认证只发送 OTP 用于测试电话号码 - Firebase Phone authentication only sending OTP For Testing Phone Numbers Firebase:未捕获错误:尚未注册组件分析 - Firebase : Uncaught Error: Component analytics has not been registered yet 是否可以通过 Firebase 无密码身份验证发送 OTP 而不是链接? - Is it possible to send an OTP instead of a link via Firebase Passwordless authentication? 获取 Firebase Phone Auth OTP 时出错 - Error while geting Firebase Phone Auth OTP
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM