reCAPTCHA container is either not found or already contains inner elements
Asked Answered
A

4

7

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

Aesthesia answered 21/7, 2017 at 7:6 Comment(1)
See if this thread helps. #44081540Varus
N
1

Here is your credible source! https://developers.google.com/recaptcha/docs/invisible

It looks like the div <div id="recaptcha-container"></div> has not added to your DOM yet which is in your class constructor.

Also Angular 2 does not want you to change the DOM directly. You should change the DOM with ElementRef or ViewChild! Good luck!

UPDATE: Here is how to add it to the dom. Run the command

iElement.html('<div id="recaptcha-container"></div>');

in angular2.

That command adds that element to the dom!

UPDATE #2: Try adding the following:

First install recaptcha from npm by doing

npm install angular2-recaptcha

Add the following to SystemJS config:

System.config({
    map: {
        'angular2-recaptcha': 'node_modules/angular2-recaptcha'
    },
    packages: {
        app: {
            format: 'register',
            defaultExtension: 'js'
        },
        'angular2-recaptcha': {defaultExtension: 'js', main:'index'}
    }
});

Then add this module:

...
import { ReCaptchaModule } from 'angular2-recaptcha';
...


...
@NgModule({
  imports: [...,ReCaptchaModule]
  })
...

Then add this to your html:

 <re-captcha site_key="<GOOGLE_RECAPTCHA_KEY>"></re-captcha>

Replace GOOGLE_RECAPTCHA_KEY with your Google reCaptcha public key

Nara answered 29/7, 2017 at 0:1 Comment(2)
sorry man, I don't understand what you mean to do, can you explain how can I fix this issue and I can vote your answer and give you the 50+ pointsAesthesia
no, because I don't know where to add it, I use type script, not javascript. I gave you the 50+ points because I appreciate your time to help me.Aesthesia
M
1

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.

Martial answered 23/8, 2018 at 6:47 Comment(0)
L
1

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://mcmap.net/q/1626828/-google-firebase-recaptcha-not-working-with-angular

Lanark answered 21/7, 2020 at 11:14 Comment(0)
M
0

Try to search in your html

<script type="text/javascript" src="angular-recaptcha.js"></script>

 <script src="https://www.google.com/recaptcha/api.js" async defer></script>


  <div class="g-recaptcha" data-sitekey="your_site_key"></div>
Misha answered 29/7, 2017 at 23:37 Comment(1)
what is the data-sitekey?Aesthesia

© 2022 - 2024 — McMap. All rights reserved.