4

Nextjs Firebase Phone Auth

First attempt useEffect()

useEffect(() => {
        window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha', {
            'size': 'invisible',
            'callback': (response) => {
                console.log("This is not fired on loading", response)
            }
        })

    }, [])

return (
        <>
            <div id="recaptcha"></div>
            <button onClick={clicked}> Click me </button>
        </>
    )

This runs, however the recaptcha doesn't work... User is forced to pick fire hydrants.

Second attempt: React Component

Inspiration: https://stackoverflow.com/a/63860925/7451631 Import this to Login page

class Recap extends Component {

  constructor(props) {
    super(props);
    this.signIn = this.signIn.bind(this);
  }

  componentDidMount() {
    window.reCaptchaVerifier = new firebase.auth.RecaptchaVerifier(this.recaptcha, {
      'size': 'invisible',
      'callback': function (response) {
        console.log("Magic", response)
      }
    })
  }

  signIn() {
    firebase.auth().signInWithPhoneNumber(phoneNumber, window.reCaptchaVerifier).catch((error) => {
      console.log(error)
    })
  }

  render() {
    return (
      <>
        <div ref={(ref) => this.recaptcha = ref} onClick={this.signIn}> Clik meeeee </div>
      </>
    )
  }
}

Works! I got a ugly solution while typing up this question. If anyone knows how to make it nicer or can explain why the first attempt did not work that would be dope.

tintin
  • 107
  • 2
  • 6
  • Maybe the casing in `reCaptchaVerifier` is relevant here? You're using `recaptchaVerifier` on the first attempt, and `reCaptchaVerifier` on the second one. – juliomalves Mar 22 '21 at 15:56
  • I'm wondering this too, it's really weird why the first method does not work – Chandraaditya Nov 19 '21 at 21:21

1 Answers1

1

here is my solutions:

    import { createFirebaseApp } from '@utils/firebase';
    import { getAuth, PhoneAuthProvider, RecaptchaVerifier, signInWithCredential } from 'firebase/auth';
    import { useState } from 'react';
    
    export default function Example() {
      const app = createFirebaseApp();
      const auth = getAuth(app);
    
      const [code, setCode] = useState('');
      const [verificationId, setVerificationId] = useState('');
    
      const signInWithPhone1 = async () => {
        const applicationVerifier = new RecaptchaVerifier(
          'sign-in-button',
          {
            size: 'invisible',
          },
          auth,
        );
    
        const provider = new PhoneAuthProvider(auth);
        const vId = await provider.verifyPhoneNumber('+855012000001', applicationVerifier);
    
        setVerificationId(vId);
      };
    
      const verify = async () => {
        const authCredential = PhoneAuthProvider.credential(verificationId, code);
        const userCredential = await signInWithCredential(auth, authCredential);
        console.log('verify: ', userCredential);
      };
    
      return (
        <>
          <button id="sign-in-button" onClick={signInWithPhone1}>
            SignIn With Phone1
          </button>
    
          <div>
            <input type="text" value={code} onChange={(v) => setCode(v.target.value)} />
            <button onClick={verify}>Verify</button>
          </div>
        </>
      );
    }
Limbo
  • 2,123
  • 21
  • 41
sun sreng
  • 587
  • 6
  • 7