Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase RecaptchaVerifier.clear() has no effect

I have react web app where I want to implement phone auth. I have initialized recaptchaVerifier based on docs and examples. However if I want to submit the form again (say because of the error). I get error: Error: reCAPTCHA has already been rendered in this element.

I have tried to remove the verifier using .clear method, but that seems to have no effect. Bellow is example code.

Is there something I have overlooked?

Thank you.

class PhoneAuth extends React.Component {
  static contextTypes = {
    firebase: PropTypes.object.isRequired,
  };

  state = {
    phone: '',
  }

  onChangeHandler = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    })
  }

  onPhoneLoginSubmit = (e) => {
    const { onVerificationSend } = this.props
    const {phone} = this.state
    const {firebase }=this.context

    e.preventDefault()

    this.applicationVerifier = new firebase.auth.RecaptchaVerifier(
      'recaptcha-container',
      { size: 'invisible' }
    );

    firebase.auth().signInWithPhoneNumber(phone, this.applicationVerifier)
      .then((result) => {
        onVerificationSend(result.verificationId)
        this.applicationVerifier.clear()
      })
      .catch (error => {
        this.setState({formError: error})
        this.applicationVerifier.clear()
      })
  }

  render() {
    const { intl } = this.props;
    const { phone, formError } = this.state

    return (
      <div>
      <form onSubmit={this.onPhoneLoginSubmit} name="phone-signin" method="post">
              <input
                id="phone"
                name="phone"
                type="phone"
                onChange={this.onChangeHandler}
                value={phone}
              />
              <label className="input__label" htmlFor="email">
               phone number
              </label>

            {formError && (
              <p >
                {formError.code}
              </p>
            )}

            <button
              type="submit"
            >
              sign in
            </button>
          </form>
          <div id="recaptcha-container"></div>
      </div>
    )
  }
}
like image 716
Tomáš Pustelník Avatar asked Jan 02 '23 03:01

Tomáš Pustelník


1 Answers

So, I have figure it out. The problem wasn't clear() method - that is working properly. But I have to recreate the captcha container from scratch myself. Doc isn't clear about it, so that's confused me. In the docs there is:

Clears the reCAPTCHA widget from the page and destroys the current instance.

So I thought that it will be removed via the method.

So, right now I have this code in the render method:

<div ref={ref => this.recaptchaWrapperRef = ref}>
  <div id="recaptcha-container"></div>
</div>

and then in the submit callback:

if (this.applicationVerifier && this.recaptchaWrapperRef) {
  this.applicationVerifier.clear()
  this.recaptchaWrapperRef.innerHTML = `<div id="recaptcha-container"></div>`
}

// Initialize new reCaptcha verifier
this.applicationVerifier = new firebase.auth.RecaptchaVerifier(
  'recaptcha-container',
  { size: 'invisible' }
);

This is the only way how I manage to do it in react. If someone still ahve better way to do it, feel free to post it. As I think this is pretty ugly (for React).

like image 160
Tomáš Pustelník Avatar answered Jan 11 '23 21:01

Tomáš Pustelník