我正在尝试使用Ionic2/typescript进行电话号码身份验证,并像这样初始化recaptcha验证器:
.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
第一次探索离子和火碱的世界,我发现很难理解这个问题。以前有人遇到并解决了这个问题吗?任何见解都会有所帮助。
你应该在view init "ionViewDidEnter"之后调用它
this.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
我认为问题是
<div id="recaptcha-container"></div>
尚未添加到 DOM 中(在您的类的构造函数中(。 您必须等待它执行此操作。
有一件事是 Angular 2 希望你不要直接访问/操作 DOM。你应该用ElementRef(这里有一个例子,你必须等待ngAfterContentInit生命周期事件(或ViewChild来做这个"Angular方式"。
您还可以添加延迟来加载验证码。它为我做了诀窍。
.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>
好吧,问题是,您已经在 html 格式副本之前编写了验证码,如果使用 ionic4,则在构造函数或 oninit 中。把它写在ionViewDidEnter中。那时 HTML 已经呈现,到那时可以在 html 文档中找到具有给定 id 的节点。
在构造函数中,页面尚未加载,因此 DOM 元素不存在。
因此,您必须将其放置在init上的任一ng中
(最快(
ngOnInit(){
}
或离子视图将进入(最佳(
ionViewWillEnter(){
}
或离子视图确实进入(最安全(
ionViewDidEnter(){
}
或者你可以在构造函数中使用计时器问题是估计所有页面采用不同持续时间时的持续时间
var duration = 3000;
//in milliseconds. therefore 3 seconds.
//which may either late or early
setTimeout(()=>{
}, duration)
查看离子生命周期以更好地了解
使用钩子
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();
}, []);
这种方法帮助了我:
- 创建组件验证码。
- 将您的容器验证码带到您的新组件。
- 将 Firebase 和 recaptchaVerifier 配置的初始化应用到您的验证码组件中。
- 将其插入任何需要的地方。
在苗条中遇到了同样的问题,但是在 ReCAPTCHA 上加载 OnMount 节省了一天