Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase phone sign-in, where to put firebase recaptcha code?

Edit:

To my knowledge this won't actually work with react doing it this way since it is referencing a container with the id of recaptcha-container from the window object. The reason being because react uses the bundle js script to load its rendered data. This is why no matter where I put this I keep getting the: reCAPTCHA container is either not found or already contains inner elements!

So it may be better if I ask how to implement this in for React rather than where to put this bit of code. If enough people can confirm this I will edit the title as well.

End of Edit

This may be a general question , but I have not found anything on how to use the phone sign in with firebase and react. I have no clue where to put this bit of code into my react project (In a component, inside the root index.js, etc...) Please let me know if I need to include or ask this question differently so I can change it. Here is the code that I am struggling with as far as location goes:

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': function(response) {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': function() {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

I tried putting this inside a component inside the componentWillMount() and nothing at all happened. I also tried putting this in my root index.js above the reactDOM.render bit and got something like:

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

Again please let me know what I can add to this or if I can improve my question.

like image 648
Taylor Austin Avatar asked Jan 19 '18 21:01

Taylor Austin


People also ask

How do I turn off reCAPTCHA in Firebase phone Auth OTP Web?

Don't forget to go in Firebase Project Settings > App check > and Register firebase project in SafetyNet and Play Integrity register with default time token 1 hour and u will remove reCaptcha from phone auth OTP! That's awesome.


2 Answers

  1. The reason why it did not work in componentWillMount is because the container id you gave is not present in the dom yet. (will mount)
  2. RecaptchaVerifier requires an empty div to be present for authentication. When you put the function inside render, it gets called again when the div will not be empty.

Now coming to the solution,

componentDidMount() {
  window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier(this.recaptcha, {
    'size': 'normal',
    'callback': function (response) {
      // reCAPTCHA solved, allow signInWithPhoneNumber.
      // ...
    },
    'expired-callback': function () {
      // Response expired. Ask user to solve reCAPTCHA again.
      // ...
    }
 });
 window.recaptchaVerifier.render().then(function (widgetId) {
   window.recaptchaWidgetId = widgetId;
 });
}

and in the HTML,

<div ref={(ref)=>this.recaptcha=ref}></div>

Instead of providing the id of the recaptcha div, we provide the reference of the DOM element (as is the practice in the React world), you can see the API of RecaptchaVerifier for more information.

like image 173
Agney Avatar answered Oct 24 '22 11:10

Agney


Or, with React.useRef hook and TypeScript:

import React, {
  useEffect
} from 'react';
import app from 'firebase/app';
import 'firebase/auth';
import 'firebase/analytics';
import 'firebase/firestore';

export const LoginScreen: React.FunctionComponent = () => {
  const app: app.app.App | null = app.initializeApp();
  const captchaRef = React.useRef(null);

  const OnPressLogin = async(phone: string) => {
    this.auth ? .signInWithPhoneNumber(
      phone,
      new app.auth.RecaptchaVerifier(captchaRef.current, {
        size: 'invisible',
        callback: (response: any) => {
          console.info('Invisible Captcha', response);
          // reCAPTCHA solved, allow signInWithPhoneNumber.
          onCaptcha();
        },
      }),
    );
  };

  return ( <>
        <div id="recaptcha-container" ref={captchaRef}></div>
        <LoginForm disabled={isBusy} onSubmit={OnPressLogin} />
  );
};
like image 31
Thomas Hagström Avatar answered Oct 24 '22 11:10

Thomas Hagström