[英]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.