Skip to main content

Firebase Two-Factor Authentication with Typescript: Error (auth/argument-error)

I have followed the code from the official docs. When you scroll down to the full code, it has two things that make problems. First of all, this seems weird:

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
const auth = getAuth();

They define auth after using it for recaptchaVerifier. But that seems like a typo, so I just switched these two lines.

But I cannot resolve the second issue. Their code is in JavaScript, my code is in TypeScript. They use undefined as an argument in the definition of recaptchaVerifier:

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);

The second argument of the constructor is undefined. Since TypeScript does not allow that, I tried many things, for example these:

  1. const undef: any = undefined; const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undef, auth);
  2. const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', { size: 'invisible' }, auth);

But it ALWAYS gives this error in the console:

ERROR FirebaseError: Firebase: Error (auth/argument-error).
    at createErrorInternal (index-0bb4da3b.js:474:41)
    at _assert (index-0bb4da3b.js:480:15)
    at new RecaptchaVerifier (index-0bb4da3b.js:7369:9)

I could not find anything that helped me fix this error in the internet.


Here is my full code:

LogIn(email: string, password: string) {
    const auth = getAuth();
    
    const undef: any = undefined;
    const recaptchaVerifier = new RecaptchaVerifier(
      'recaptcha-container-id',
      undef,
      auth
    );

    /* It never reaches this code below here since new RecaptchaVerifier() always throws an error */

    
    return signInWithEmailAndPassword(auth, email, password)
      .then((result) => {
        this.afAuth.authState.subscribe((user) => {
          if (user) {
            this.router.navigate(['home']);
          }
        });

      })
      .catch((error) => {
        if (error.code == 'auth/multi-factor-auth-required') {
          // The user is a multi-factor user. Second factor challenge is required.
          const auth = getAuth();
          let resolver = getMultiFactorResolver(auth, error);

          const phoneInfoOptions = {
            multiFactorHint: resolver.hints[0],
            session: resolver.session
          };

          // Send SMS verification code.
          const phoneAuthProvider = new PhoneAuthProvider(auth);

          phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
              .then((verificationId) => {
                  // verificationId will be needed for sign-in completion.
                  
                  // Ask user for the SMS verification code via prompt (yeah, very bad UI)
                  const verificationCode = prompt("Enter the verification code we sent to your number");
                  
                  if (verificationCode !== null) {
                    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
                    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);

                    // Complete sign-in.
                    return resolver.resolveSignIn(multiFactorAssertion);

                  } else {
                    this.toast.error("Entered wrong code");
                    return null;
                  }
              })
              .then((userCredential) => {
                // User successfully signed in with the second factor phone number.
                this.toast.success("Code is correct. Logged in");
                this.afAuth.authState.subscribe((user) => {
                  if (user) {
                    this.router.navigate(['home']);
                  }
                });

              })
              .catch((error) => {
                console.log(error);
    
                // failed
                this.toast.error(error.message);
              });

        } else if (error.code == 'auth/wrong-password') {
          this.toast.error(error.message);
        }
      });
  }

I am using Angular and angularfire. The code above is not called directly from a component, but from a service. That service though is called from my LoginComponent.


Edit. My imports are:

import { Injectable, NgZone } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import {
  AngularFirestore,
} from '@angular/fire/compat/firestore';
import { Router } from '@angular/router';
import { child, get, getDatabase, ref, set } from "firebase/database";
import { HotToastService } from '@ngneat/hot-toast';
import firebase from "firebase/compat/app";
import { getAuth, getMultiFactorResolver, GoogleAuthProvider, PhoneAuthProvider, PhoneMultiFactorGenerator, RecaptchaVerifier, signInWithEmailAndPassword, signInWithPopup } from 'firebase/auth';
Via Active questions tagged javascript - Stack Overflow https://ift.tt/2HwmLzr

Comments

Popular posts from this blog

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console...

How to split a rinex file if I need 24 hours data

Trying to divide rinex file using the command gfzrnx but getting this error. While doing that getting this error msg 'gfzrnx' is not recognized as an internal or external command Trying to split rinex file using the command gfzrnx. also install'gfzrnx'. my doubt is I need to run this program in 'gfzrnx' or in 'cmdprompt'. I am expecting a rinex file with 24 hrs or 1 day data.I Have 48 hrs data in RINEX format. Please help me to solve this issue. source https://stackoverflow.com/questions/75385367/how-to-split-a-rinex-file-if-i-need-24-hours-data