Reputation: 3777
Hi, I am using Firebase's invisible reCaptcha for phone number authentication in my React JS application. As per the documentation of Firebase you need to provide id (e.g. sign-in-button
) of the button which handles submit of login form.
Once user click on that button, Firebase's invisible reCaptcha should kick in and checks if it has been resolved by the user or not. If reCaptcha is resolved, a callback
provided by new firebase.auth.RecaptchaVerifier('...', {})
will be fired. In that callback we are supposed to send an OTP code to user's phone number.
What's the happening is that the callback
is not being fired unless the OTP isn’t sent on submit of the login form which doesn’t make sense because sending OTP needs to handled by the callback provided by invisible reCaptcha and not by sending the OTP with onSubmit of the form.
"firebase": "^7.15.1",
import React, { Component } from 'react';
import firebase from 'firebase/app';
import 'firebase/auth';
firebase.initializeApp({
apiKey: 'xxx',
authDomain: 'xxx',
databaseURL: 'xxx',
projectId: 'xxx',
storageBucket: 'xxx',
messagingSenderId: 'xxx',
appId: 'xxx',
measurementId: 'xxx',
});
class App extends Component {
componentDidMount() {
window.reCaptchaVerifier = new firebase.auth.RecaptchaVerifier('login-button', {
size: 'invisible',
callback: () => {
// callback is not being fired automatically
// but after the OTP has been sent to user's
// phone number which makes this callback useless
// as opposed to Firebase's documentation
},
});
}
handleSubmit = event => {
event.preventDefault();
firebase
.auth()
.signInWithPhoneNumber('+1 XXX-XXX-XXXX', window.reCaptchaVerifier)
.then(confirmationResult => {
window.confirmationResult = confirmationResult;
})
.catch(() => {});
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<input />
<button id="login-button">Submit</button>
</form>
);
}
}
Upvotes: 9
Views: 7725
Reputation: 986
This is what I'm using, seems to work well
const [token, setToken] = useState("");
useEffect(() => {
new firebase.auth.RecaptchaVerifier("request-otp", { size: "invisible" })
.verify()
.then(setToken);
}, []);
Upvotes: 7
Reputation: 13058
Usually, reCAPTCHA needs to be rendered before it is used. So, for example, the following code works. The only modifications from the code in the question are:
componentDidMount
onSumbit
is not used therefore (it actually never fires in this scenario, because reCAPTCHA callback processes the submit event instead)Working solution with pre-render:
class App extends Component {
componentDidMount() {
const reCaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
size: 'invisible',
callback: function (response) {
console.log('It works!');
},
});
reCaptchaVerifier.render();
}
render() {
return (
<form>
<input />
<button id="sign-in-button">Submit</button>
</form>
);
}
}
Upvotes: 3