Firebase RecaptchaVerifier.clear()无效

时间:2018-07-11 12:02:43

标签: reactjs firebase firebase-authentication

我有我要在其中实现电话验证的Web应用程序。我已经基于文档和示例初始化了recaptchaVerifier。但是,如果我想再次提交表单(例如由于错误)。我收到错误消息:Error: reCAPTCHA has already been rendered in this element

我尝试使用.clear方法删除验证程序,但这似乎没有效果。波纹管是示例代码。

有什么我忽略的东西吗?

谢谢。

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>
    )
  }
}

4 个答案:

答案 0 :(得分:2)

所以,我知道了。问题不是clear()方法-工作正常。但是我必须从头开始重新创建验证码容器。 Doc不清楚,所以这让我感到困惑。在文档中有:

从页面上清除reCAPTCHA小部件并破坏当前实例。

所以我认为它将通过该方法删除。

所以,现在我在render方法中有以下代码:

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

,然后在提交回调中:

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' }
);

这是我做出反应的唯一方法。如果有人仍然有更好的方法,请随时发布。我认为这很丑陋(对于React)。

答案 1 :(得分:0)

onPhoneLoginSubmit()方法之外使用captchaVarifier

请勿使用

this.applicationVerifier

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

请使用window.recaptchaVerifier并删除.clear()

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

onPhoneLoginSubmit = (e) => {
firebase.auth().signInWithPhoneNumber(phone, window.recaptchaVerifier)
  .then((result) => {
    onVerificationSend(result.verificationId)

  })
  .catch (error => {
    this.setState({formError: error})

  })
}

然后使用setTimeout()函数延迟1或2秒,如果您不使用setTimeout(),则重新配置容器<div id="recaptcha-container"></div>将在此代码之后执行,这将产生错误

请使用setTimeout(),例如下面的示例

 componentWillMount(){
 setTimeout(() => {
  window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
    "recaptcha-container",
    {
      size: "invisible"
    }
  );
 }, 2000);
}
 onPhoneLoginSubmit = (e) => {
firebase.auth().signInWithPhoneNumber(phone, window.recaptchaVerifier)
  .then((result) => {
    onVerificationSend(result.verificationId)

  })
  .catch (error => {
    this.setState({formError: error})

  })
}

答案 2 :(得分:0)

我在React上也遇到了同样的问题。但有一个参考的问题。所以我使用父div元素的ID创建了一个新实例

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

在提交回调中添加它。

document.getElementById("recaptcha-container").innerHTML = "<div id='recaptcha'></div>";

答案 3 :(得分:0)

只需在catch中使用window.recaptchaVerifier.reset() 例如

const signInWithPhoneNumber = (fullMobile) => {
return new Promise((resolve, reject) => {
  auth.signInWithPhoneNumber(fullMobile, window.recaptchaVerifier).then(res => {
    resolve(res)
  })
    .catch(error => {
      console.log(error)
      window.recaptchaVerifier.reset()
      reject(error)
    })
})

}