'Firebase Typescript API auth - account-exists-with-different-credential

hope anyone can help me with my problems. I created a login page with a firebase where I can login with facebook and gmail. but unfortunately, it gives me an error with a code (auth/account-exists-with-different-credential). can somebody give me a clue what can I do to solve this problem?

here is my code

const actions: ActionTree<RootState, RootState> = {
  onAuthStateChangedAction(
    state,
    { authUser }: { authUser: User; additionalUserInfo: AdditionalUserInfo }
  ) {
    if (authUser) {
      // bind user data, so do not need to bind on each components
      this.dispatch('users/bindCurrentUser')
    }
    if (!authUser) {
      // remove state
      state.commit('SET_USER', null)

      // redirect from here
      return this.$router.push({
        path: '/',
      })
    }

    // check login or register
    const { uid, email, emailVerified, displayName, photoURL } = authUser
    state.commit('SET_USER', {
      uid,
      email,
      emailVerified,
      displayName,
      photoURL,
    })
  },
  
  // request otp
  async requestOTP(_state, { email }: { email: string }) {
    const functionRef = this.$fire.functions.httpsCallable('authRequestOTP')
    await functionRef({ email })
  },
  
  // login with otp
  async loginWithOTP(
    _state,
    {
      email,
      otp,
      referralCode,
    }: { email: string; otp: string; referralCode?: string }
  ) {
    const functionRef = this.$fire.functions.httpsCallable('authVerifyOTP')
    const token = (await functionRef({ email, otp })).data
    if (!token) throw new Error('token not valid')

    // login with selected auth provider
    const result = await this.$fire.auth.signInWithCustomToken(token)
    if (!result) throw new Error('error')

    // check if new user
    const { user } = result
    if (!user || !user.uid) throw new Error('no user object')
    const userSnap = await this.$fire.firestore
      .collection(COLLECTION.USER)
      .doc(user.uid)
      .get()

    // if new user, add to collection
    //  and go to
    let nextPage = 'profile-user'
    if (!userSnap.exists) {
      const newUserData = {
        id: user.uid,
        name: '',
        email,
        phone: '',
        imageUrl: '',
      }
      this.dispatch('users/add', newUserData)
      nextPage = 'auth-profile'
    }
    return this.$router.push({ name: nextPage, query: { code: referralCode } })
  },
  
  // login with provider
  async login(
    _state,
    { provider, referralCode }: { provider: string; referralCode?: string }
  ) {
    let authProvider = null

    // prepare auth provider
    if (provider === 'google')
      authProvider = new this.$fireModule.auth.GoogleAuthProvider()
    if (provider === 'facebook')
      authProvider = new this.$fireModule.auth.FacebookAuthProvider()
    if (!authProvider) throw new Error('error')

    // login with selected auth provider
    const result = await this.$fire.auth.signInWithPopup(authProvider)
    if (!result) throw new Error('error')
      
    
    // parse result
    const { user, additionalUserInfo } = result
    if (!user) throw new Error('no user object')
    const { isNewUser, profile, username } = additionalUserInfo ?? {}
    const userProfile = profile as
      | GoogleAdditionalUserInfo
      | FacebookAdditionalUserInfo
      | null

    // if new user, add to collection
    let nextPage = 'profile-user'
    if (isNewUser) {
      const newUserData = {
        id: user.uid,
        name: username ?? user.displayName,
        email: userProfile?.email ?? user.email,
        phone: user.phoneNumber ?? '',
        imageUrl: userProfile?.picture ?? user.photoURL,
      }
      this.dispatch('users/add', newUserData)
      nextPage = 'auth-profile'
    }

    this.$router.push({ name: nextPage, query: { code: referralCode } })
  },
  
  // complete profile
  async completeProfile(
    _state,
    {
      id,
      phone,
      name,
      referralCode,
    }: { id: string; phone: string; name: string; referralCode: string }
  ) {
    // update user profile
    await this.$fire.firestore.collection(COLLECTION.USER).doc(id).update({
      phone,
      name,
    })

    // claim referral reward
    if (referralCode) {
      await this.$fire.functions.httpsCallable('referralClaim')({
        referredId: id,
        code: referralCode,
      })
    }

    return true
  },
}


Solution 1:[1]

That error message typically indicates that an account exists with that email address, but that either the password doesn't match or (more likely here) that the existing account is with a different provider than the one that's trying to sign in now. Simpler put: you signed in to that account with Facebook before and are now trying to sign in with Google (or vice versa).

While it is possible to associate multiple providers (like Facebook and Google) with a single user account, this does require that you link those providers to the account.

If you're not trying to link multiple providers, but don't know what provider the user used previously, the flow normally is:

  1. Ask the user to enter their email address (or get it from somewhere else).
  2. Call fetchSignInMethodsForEmail to determine which providers can be used to sign in with that email address.
  3. Call the correct sign-in method, or show a screen allowing the user to pick the provider to sign in with (if there are multiple providers in step 2).

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 Frank van Puffelen