Vincule vários provedores de autenticação a uma conta usando JavaScript

Você pode permitir que os usuários façam login no seu aplicativo usando vários provedores de autenticação vinculando as credenciais do provedor de autenticação a uma conta de usuário existente. Os usuários são identificáveis ​​pelo mesmo ID de usuário do Firebase, independentemente do provedor de autenticação usado para fazer login. Por exemplo, um usuário que fez login com uma senha pode vincular uma conta do Google e fazer login com qualquer um dos métodos no futuro. Ou um usuário anônimo pode vincular uma conta do Facebook e, posteriormente, fazer login no Facebook para continuar usando seu aplicativo.

Antes de você começar

Adicione suporte para dois ou mais provedores de autenticação (possivelmente incluindo autenticação anônima) ao seu aplicativo.

Para vincular credenciais de um provedor de autenticação, como Google ou Facebook, a uma conta de usuário existente:

  1. Faça login do usuário usando qualquer provedor ou método de autenticação.
  2. Obtenha o objeto AuthProvider que corresponde ao provedor que você deseja vincular à conta do usuário. Exemplos:

    Web modular API

    import { GoogleAuthProvider, FacebookAuthProvider, TwitterAuthProvider, GithubAuthProvider } from "firebase/auth";
    
    const googleProvider = new GoogleAuthProvider();
    const facebookProvider = new FacebookAuthProvider();
    const twitterProvider = new TwitterAuthProvider();
    const githubProvider = new GithubAuthProvider();

    Web namespaced API

    var googleProvider = new firebase.auth.GoogleAuthProvider();
    var facebookProvider = new firebase.auth.FacebookAuthProvider();
    var twitterProvider = new firebase.auth.TwitterAuthProvider();
    var githubProvider = new firebase.auth.GithubAuthProvider();
  3. Solicite ao usuário que faça login no provedor que você deseja vincular. Você pode solicitar que seus usuários façam login abrindo uma janela pop-up ou redirecionando para a página de login do provedor. O método de redirecionamento é preferido em dispositivos móveis.
    • Para fazer login com uma janela pop-up, chame linkWithPopup :

      Web modular API

      import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth";
      const provider = new GoogleAuthProvider();
      
      const auth = getAuth();
      linkWithPopup(auth.currentUser, provider).then((result) => {
        // Accounts successfully linked.
        const credential = GoogleAuthProvider.credentialFromResult(result);
        const user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });

      Web namespaced API

      auth.currentUser.linkWithPopup(provider).then((result) => {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    • Para fazer login redirecionando para a página de login do provedor, chame linkWithRedirect : siga as práticas recomendadas ao usar `linkWithRedirect`.

      Web modular API

      import { getAuth, linkWithRedirect, GoogleAuthProvider } from "firebase/auth";
      const provider = new GoogleAuthProvider();
      
      const auth = getAuth();
      linkWithRedirect(auth.currentUser, provider)
        .then(/* ... */)
        .catch(/* ... */);

      Web namespaced API

      auth.currentUser.linkWithRedirect(provider)
        .then(/* ... */)
        .catch(/* ... */);
      Depois que o usuário faz login, ele é redirecionado de volta para sua página. Em seguida, você pode recuperar o resultado do login chamando getRedirectResult quando sua página for carregada:

      Web modular API

      import { getRedirectResult } from "firebase/auth";
      getRedirectResult(auth).then((result) => {
        const credential = GoogleAuthProvider.credentialFromResult(result);
        if (credential) {
          // Accounts successfully linked.
          const user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });

      Web namespaced API

      auth.getRedirectResult().then((result) => {
        if (result.credential) {
          // Accounts successfully linked.
          var credential = result.credential;
          var user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    Se o login do usuário for bem-sucedido, a conta do usuário com o provedor será vinculada à conta do usuário no seu projeto do Firebase.

    A vinculação da conta falhará se as credenciais já estiverem vinculadas a outra conta de usuário. Nessa situação, você deve mesclar as contas e os dados associados conforme apropriado para seu aplicativo:

    Web modular API

    import { getAuth, signInWithCredential, linkWithCredential, OAuthProvider } from "firebase/auth";
    
    // The implementation of how you store your user data depends on your application
    const repo = new MyUserDataRepo();
    
    // Get reference to the currently signed-in user
    const auth = getAuth();
    const prevUser = auth.currentUser;
    
    // Get the data which you will want to merge. This should be done now
    // while the app is still signed in as this user.
    const prevUserData = repo.get(prevUser);
    
    // Delete the user's data now, we will restore it if the merge fails
    repo.delete(prevUser);
    
    // Sign in user with the account you want to link to
    signInWithCredential(auth, newCredential).then((result) => {
      console.log("Sign In Success", result);
      const currentUser = result.user;
      const currentUserData = repo.get(currentUser);
    
      // Merge prevUser and currentUser data stored in Firebase.
      // Note: How you handle this is specific to your application
      const mergedData = repo.merge(prevUserData, currentUserData);
    
      const credential = OAuthProvider.credentialFromResult(result);
      return linkWithCredential(prevUser, credential)
        .then((linkResult) => {
          // Sign in with the newly linked credential
          const linkCredential = OAuthProvider.credentialFromResult(linkResult);
          return signInWithCredential(auth, linkCredential);
        })
        .then((signInResult) => {
          // Save the merged data to the new user
          repo.set(signInResult.user, mergedData);
        });
    }).catch((error) => {
      // If there are errors we want to undo the data merge/deletion
      console.log("Sign In Error", error);
      repo.set(prevUser, prevUserData);
    });

    Web namespaced API

    // The implementation of how you store your user data depends on your application
    var repo = new MyUserDataRepo();
    
    // Get reference to the currently signed-in user
    var prevUser = auth.currentUser;
    
    // Get the data which you will want to merge. This should be done now
    // while the app is still signed in as this user.
    var prevUserData = repo.get(prevUser);
    
    // Delete the user's data now, we will restore it if the merge fails
    repo.delete(prevUser);
    
    // Sign in user with the account you want to link to
    auth.signInWithCredential(newCredential).then((result) => {
      console.log("Sign In Success", result);
      var currentUser = result.user;
      var currentUserData = repo.get(currentUser);
    
      // Merge prevUser and currentUser data stored in Firebase.
      // Note: How you handle this is specific to your application
      var mergedData = repo.merge(prevUserData, currentUserData);
    
      return prevUser.linkWithCredential(result.credential)
        .then((linkResult) => {
          // Sign in with the newly linked credential
          return auth.signInWithCredential(linkResult.credential);
        })
        .then((signInResult) => {
          // Save the merged data to the new user
          repo.set(signInResult.user, mergedData);
        });
    }).catch((error) => {
      // If there are errors we want to undo the data merge/deletion
      console.log("Sign In Error", error);
      repo.set(prevUser, prevUserData);
    });

Para adicionar credenciais de endereço de e-mail e senha a uma conta de usuário existente:

  1. Faça login do usuário usando qualquer provedor ou método de autenticação.
  2. Solicite ao usuário um endereço de e-mail e uma nova senha.
  3. Crie um objeto AuthCredential com o endereço de e-mail e senha:

    Web modular API

    import { EmailAuthProvider } from "firebase/auth";
    
    const credential = EmailAuthProvider.credential(email, password);

    Web namespaced API

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Passe o objeto AuthCredential para o método linkWithCredential do usuário conectado:

    Web modular API

    import { getAuth, linkWithCredential } from "firebase/auth";
    
    const auth = getAuth();
    linkWithCredential(auth.currentUser, credential)
      .then((usercred) => {
        const user = usercred.user;
        console.log("Account linking success", user);
      }).catch((error) => {
        console.log("Account linking error", error);
      });

    Web namespaced API

    auth.currentUser.linkWithCredential(credential)
      .then((usercred) => {
        var user = usercred.user;
        console.log("Account linking success", user);
      }).catch((error) => {
        console.log("Account linking error", error);
      });

    A chamada para linkWithCredential falhará se as credenciais já estiverem vinculadas a outra conta de usuário. Nessa situação, você deve mesclar as contas e os dados associados conforme apropriado para seu aplicativo (veja o exemplo acima).

Você pode desvincular um provedor de autenticação de uma conta para que o usuário não possa mais fazer login nesse provedor.

Para desvincular um provedor de autenticação de uma conta de usuário, passe o ID do provedor para o método unlink . Você pode obter os IDs dos provedores de autenticação vinculados a um usuário na propriedade providerData .

Web modular API

import { getAuth, unlink } from "firebase/auth";

const auth = getAuth();
unlink(auth.currentUser, providerId).then(() => {
  // Auth provider unlinked from account
  // ...
}).catch((error) => {
  // An error happened
  // ...
});

Web namespaced API

user.unlink(providerId).then(() => {
  // Auth provider unlinked from account
  // ...
}).catch((error) => {
  // An error happened
  // ...
});