reCAPTCHA container is either not found or already contains inner elements

Viewed 6774

I'm getting error in angular 4 when i try to make phone authentication.

I got this error in console

reCAPTCHA container is either not found or already contains inner elements!

I don't see the reCAPTCHA container in my web and can't press on it.

login-page.ts

 import { Component, OnInit } from '@angular/core';
// tslint:disable-next-line:quotemark
import { Router } from "@angular/router";
// tslint:disable-next-line:quotemark
import { AuthService } from "../../core/auth.service";

import { ReactiveFormsModule } from '@angular/forms';
import * as firebase from 'firebase';


export class PhoneNumber {

  country: string;

  area: string;

  prefix: string;

  line: string;

  // format phone numbers as E.164

  get e164() {

    const num = this.country + this.area + this.prefix + this.line

    return `+${num}`

  }


}

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'user-login',
  templateUrl: './user-login.component.html',
  styleUrls: ['./user-login.component.scss']
})
export class UserLoginComponent implements OnInit {

  // phone auth
  windowRef: any;
  phoneNumber = new PhoneNumber();
  verificationCode: string;


  user: any;
  constructor(public auth: AuthService,
              private router: Router) { 

              }


  ngOnInit() {
    this.windowRef = this.auth.windowRef
    this.windowRef.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container')
    this.windowRef.recaptchaVerifier.render()


  }

  // phone auth
   sendLoginCode() {


    const appVerifier = this.windowRef.recaptchaVerifier;


    const num = this.phoneNumber.e164;

    console.log(num);
    firebase.auth().signInWithPhoneNumber(num, appVerifier)

            .then(result => {


                this.windowRef.confirmationResult = result;


            })

            .catch( error => console.log(error) );


  }

  verifyLoginCode() {

    this.windowRef.confirmationResult

                  .confirm(this.verificationCode)

                  .then( result => {


                    this.user = result.user;


    })

    .catch( error => console.log(error, 'Incorrect code entered?'));

  }




}

html code

    <div *ngIf="!auth.currentUser; else alreadyLoggedIn">

  <h3>Social Login</h3>


    <button (click)="signInWithGoogle()" class="button btn-social btn-google">
      <i class="fa fa-google-plus fa-lg"></i> Connect Google
    </button>

    <button (click)="signInWithGithub()" class="button btn-social btn-github">
      <i class="fa fa-github fa-lg"></i> Connect GitHub
    </button>

    <button (click)="signInWithFacebook()" class="button  btn-social btn-facebook">
      <i class="fa fa-facebook fa-lg"></i> Connect Facebook
    </button>

    <button (click)="signInWithTwitter()" class="button  btn-social btn-twitter">
      <i class="fa fa-twitter fa-lg"></i> Connect Twitter
    </button>

    <hr>

    <h3>Anonymous Login</h3>

      <button (click)="signInAnonymously()" class="button button-info">
        <i class="fa fa-user-secret fa-lg"></i> Connect Anonymously
      </button>

    <hr>


  <h1>Sign In with Your Phone Number</h1>


  <label for="phone">Phone Number</label><br>

  <input type="text" [(ngModel)]="phoneNumber.country"  class="input" placeholder="1"    maxlength="2">

  <input type="text" [(ngModel)]="phoneNumber.area"     class="input" placeholder="949"  maxlength="3">

  <input type="text" [(ngModel)]="phoneNumber.prefix"   class="input" placeholder="555"  maxlength="4">



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


  <button (click)="sendLoginCode()">SMS Text Login Code</button>


  <div *ngIf="windowRef.confirmationResult">

    <hr>

    <label for="code">Enter your Verification Code Here</label><br>

    <input type="text" name="code" [(ngModel)]="verificationCode">


    <button (click)="verifyLoginCode()">Verify</button>

  </div>


</div>




<ng-template #alreadyLoggedIn>
  <p class="text-success">
    Already logged in!
  </p>
</ng-template>

auth-service

import { Injectable } from '@angular/core';
import { AngularFireDatabaseModule, AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from "@angular/router";
import * as firebase from 'firebase';


@Injectable()
export class AuthService {

  authState: any = null;

  constructor(private afAuth: AngularFireAuth,
              private db: AngularFireDatabase,
              private router:Router) {

            this.afAuth.authState.subscribe((auth) => {
              this.authState = auth
            });
          }

  // Returns true if user is logged in
  get authenticated(): boolean {
    return this.authState !== null;
  }

  // Returns current user data
  get currentUser(): any {
    return this.authenticated ? this.authState : null;
  }

  // Returns
  get currentUserObservable(): any {
    return this.afAuth.authState
  }

  // Returns current user UID
  get currentUserId(): string {
    return this.authenticated ? this.authState.uid : '';
  }


  get windowRef(){
    return window
  }




}

enter image description here

I don't see the repatcha container

4 Answers

This may well be late, still putting it here for anyones benefit. I was having the same issue, following step solved it:

Replaced:

<div *ngIf="showRecaptchaDiv">

to:

<div [hidden]="!showRecaptchaDiv">

Changing the *ngIf to [hidden] worked for me.

I had same problem in my project. I want to share my solution. I hope, it becomes helpful to someone.

I realized that we should use recaptcha-container in app.component.ts. Because we should run every time this recaptcha when user login the site. I'm using this when user login. Firstly, I create a service for window variables.

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class WindowService {
 windowRef: any = window;
 constructor() { }
}

Then, I create an instance for recaptcha in app.component.ts.

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

app.component.html

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

Then, I'm getting this instance when I'm using.

loginByPhone(phone, this.windowService.windowRef.recaptchaVerifier);

You can set your confirmationResult to this variable (windowRef) that it is in service. Finally you have to reset your recaptcha, when will you use again. You can find in this link -> https://stackoverflow.com/a/45807140/9207947

Related