错误:未找到reCAPTCHA容器或已包含内部元素

时间:2017-07-07 11:50:37

标签: firebase ionic2 firebase-authentication angularfire ionic3

我正在尝试使用Ionic2 / typescript进行电话号码验证,并初始化这样的重新验证验证器:

.ts 文件

    import firebase from 'firebase';

     @IonicPage()
     @Component({
       selector: 'page-login',
       templateUrl: 'login.html',
     })

     export class LoginPage {

    public recaptchaVerifier:firebase.auth.RecaptchaVerifier;
           constructor(afAuth: AngularFireAuth, public authData: AuthProvider, public alertController: AlertController, formBuilder: FormBuilder, public navCtrl: NavController, public navParams: NavParams) {
             this.loginForm = formBuilder.group({
               phone: ['', Validators.compose([Validators.required, 
                 Validator.isValidPhone])]
             });
             try {
               this.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
             }catch(e){
               console.log("There was a problem in initializing the recapctha verifier: " + e);
             }
             this.authData.recaptchaVerifier = this.recaptchaVerifier;
           }
}

.html 文件

<ion-content padding>
  <div id="recaptcha-container"></div>
  <form [formGroup]="loginForm" (submit)="loginUser()" novalidate>

    <ion-item>
      <ion-label stacked>Phone Number</ion-label>
      <ion-input #phone formControlName="phone" type="phone" placeholder="10 digit mobile number"
        [class.invalid]="!loginForm.controls.phone.valid &&
          loginForm.controls.phone.dirty"></ion-input>
    </ion-item>
    <ion-item class="error-message" *ngIf="!loginForm.controls.phone.valid  &&
      loginForm.controls.phone.dirty">
      <p>Please enter a valid 10 digit mobile number.</p>
    </ion-item>

    <button ion-button block type="submit">
      Next
    </button>

  </form>

</ion-content>

然而,当我运行代码时,我得到了:

Error: reCAPTCHA container is either not found or already contains inner elements

首次探索离子和火基的世界,我发现很难理解这个问题。以前有人遇到并解决了这个问题吗?任何见解都会有所帮助。

7 个答案:

答案 0 :(得分:6)

you should call it after view init "ionViewDidEnter"

this.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

答案 1 :(得分:2)

您还可以添加延迟来加载验证码。它为我做了诀窍。

JS:

  var defaultApp = firebase.initializeApp(config);
  setTimeout(function() {
    window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
        'size': 'normal',
        'callback': function(response) {
            console.log("success", response);
        },
        'expired-callback': function() {
            console.log("expired-callback");
        }
    });

    recaptchaVerifier.render().then(function(widgetId) {
        window.recaptchaWidgetId = widgetId;
    });
  },2000);

HTML:

<div id="recaptcha-container"></div>

答案 2 :(得分:1)

我认为问题在于

<div id="recaptcha-container"></div>
尚未将

添加到DOM中(在类的构造函数中)。 你必须等待它才能做到这一点。

有一点是Angular 2希望您不直接访问/操作DOM。您应该使用ElementRef(此处为an example,您必须等待ngAfterContentInit生命周期事件)或ViewChild来执行此操作&#39; Angular方式&#39;

答案 3 :(得分:1)

好吧,问题是,您在html呈现之前编写了Recaptcha验证代码,如果使用ionic4,则在构造函数或oninit中编写。将其写入ionViewDidEnter。届时将呈现HTML,届时可以在html文档中找到具有给定ID的节点。

答案 4 :(得分:0)

在构造函数中,页面尚未加载,因此DOM元素不存在。
因此你必须把它放在
ng on init(最快)

ngOnInit(){

}

或离子视图将进入(最佳)

ionViewWillEnter(){

}

或离子视图确实进入(最安全)

ionViewDidEnter(){

}

或者您可以在构造函数中使用计时器 问题是估计所有页面采用不同持续时间时的持续时间

var duration = 3000; 
//in milliseconds. therefore 3 seconds. 
//which may either late or early
setTimeout(()=>{

}, duration)

查看离子生命周期以获得更好的理解

答案 5 :(得分:0)

使用钩子

useEffect(() => {
    recaptchaVerifierRef.current = new Firebase.auth.RecaptchaVerifier(
      'recaptcha-container',
      {
        size: 'invisible',
        callback: function (response) {
          console.log('success', response);
        },
        'expired-callback': function () {
          console.log('expired-callback');
        },
      },
    ).verify();
  }, []);

答案 6 :(得分:0)

这种方法对我有帮助:

  1. 创建组件验证码。
  2. 将您的容器验证码带到您的新组件中。
  3. 将 firebase 和 recaptchaVerifier 配置初始化到您的验证码组件。
  4. 将其插入任何需要的地方。