'How can I get the credential from linkWithPopup when it has an error?

I am implementing anonymous login, but when user decides to log in with another credential from Google Popup, it gives me an error - auth/credential-already-in-use.

I know that the problem is that the user is already registered, what I am trying to achieve is that if the user is already registered, he will be signed in to the existing account, based on what he provided linkWithPopup credential. The provider is Google

I think this is related to SDK 9

What I tried:

import {
  linkWithPopup,
  signInWithCredential,
} from "firebase/auth";

const isAnnon = auth.currentUser?.isAnonymous;
const annonUser = auth.currentUser;

  try {
      const userCredential = await linkWithPopup(annonUser, provider);
  } 
  catch (e: any) {
  if (e?.code === "auth/credential-already-in-use") {
          console.log(e);
          const login = await signInWithCredential(auth, e.credential)
            .then((user) => {
              console.log(user);
            })
            .catch((e: any) => {
              console.log(e);
            });
      }
   }

It works when the user is new, but when I try to login to an existing user (without the link), it doesn't let me because e.credential is undefined always.

I also tried to use .then instead of async but I still don't get the credential. I think it has something to do with the imports - it is the new firebase SDK

Thank you!



Solution 1:[1]

For those who need the solution for this I just found it! You should import GoogleAuthProvider from firebase/auth, then use it like this:

import {
  GoogleAuthProvider,
} from "firebase/auth";

GoogleAuthProvider.credentialFromError(error);

Full code:

import {
  linkWithPopup,
  signInWithCredential,
  GoogleAuthProvider
} from "firebase/auth";

const isAnnon = auth.currentUser?.isAnonymous;
const annonUser = auth.currentUser;

  try {
      const userCredential = await linkWithPopup(annonUser, provider);
  } 
  catch (error: any) {
  if (error?.code === "auth/credential-already-in-use") {
          const credential: any = GoogleAuthProvider.credentialFromError(error);
          const login = await signInWithCredential(auth, credential)
            .then((user) => {
              console.log(user);
            })
            .catch((error: any) => {
              console.log(error);
            });
      }
   }

This works perfectly!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1