Como vincular vários provedores a uma conta

Neste documento, você verá como vincular vários provedores a uma única conta do Identity Platform.

O Identity Platform usa um ID exclusivo para identificar usuários. Isso permite que os usuários façam login na mesma conta com provedores diferentes. Por exemplo, um usuário que inicialmente se registra com um número de telefone pode vincular a Conta do Google dele posteriormente e usar um dos métodos para fazer login.

Antes de começar

Adicione ao app o suporte para dois ou mais provedores de identidade.

Como ativar ou desativar a vinculação de contas

A configuração da vinculação de conta determina como o Identity Platform lida com os usuários que tentam fazer login com o mesmo e-mail usando diferentes provedores.

  • Contas vinculadas que usam o mesmo e-mail: o Identity Platform gerará um erro caso um usuário tente fazer login com um e-mail que já esteja em uso. O app pode identificar esse erro e vincular o novo provedor à conta atual.

  • Criar várias contas para cada provedor de identidade: uma nova conta de usuário do Identity Platform será criada sempre que um usuário fizer login com um provedor diferente.

Para escolher uma configuração:

  1. Acesse a página Configurações do Identity Platform no Console do Cloud.

    Ir para a página "Configurações"

  2. Selecione uma configuração em Vinculação da conta do usuário.

  3. Clique em Save.

Como vincular credenciais de provedores federados

Para vincular credenciais de um provedor federado:

  1. Faça login do usuário com um provedor ou método de autenticação.

  2. Consiga o objeto do provedor que corresponde ao provedor que você quer vincular à conta do usuário. Exemplo:

    JavaScript

    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 que o usuário faça login com o provedor que você quer vincular. Você pode abrir uma janela pop-up ou redirecionar a página atual. O redirecionamento é mais fácil para usuários de dispositivos móveis.

    Para mostrar um pop-up, chame linkWithPopup():

    JavaScript

    auth.currentUser.linkWithPopup(provider).then((result) => {
      // Accounts successfully linked.
      var credential = result.credential;
      var user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    Para redirecionar a página, primeiro chame linkWithRedirect():

    JavaScript

    auth.currentUser.linkWithRedirect(provider)
      .then(/* ... */)
      .catch(/* ... */);

    Depois que o usuário fizer login, ele será redirecionado ao seu app. Em seguida, recupere o resultado do login chamando getRedirectResult():

    JavaScript

    auth.getRedirectResult().then((result) => {
      if (result.credential) {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

A conta do usuário com o provedor federado agora está vinculada à conta do Identity Platform e o provedor pode ser usado para fazer login.

Como vincular credenciais de e-mail e senha

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

  1. Faça login do usuário com um provedor ou método de identidade.

  2. Solicite ao usuário um endereço de e-mail e uma senha.

  3. Crie um objeto AuthCredential com o endereço de e-mail e a senha:

    JavaScript

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

    JavaScript

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

As credenciais de e-mail e senha agora estão vinculadas à conta do Identity Platform do usuário e podem usá-las para fazer login.

Como processar o erro account-exists-with-different-credential

Se você tiver ativado a configuração Vincular contas que usam o mesmo e-mail, o Identity Platform gerará um erro quando um usuário tentar fazer login com um provedor usando um e-mail já associado com uma conta atual.

Para lidar com esse erro, solicite que o usuário faça login com uma conta atual. Em seguida, chame linkWithCredential(), linkWithPopup() ou linkWithRedirect() para associar o novo provedor à conta dele.

O exemplo a seguir mostra como tratar esse erro quando um usuário tenta fazer login usando o Facebook:

JavaScript

// User tries to sign in with Facebook.
auth.signInWithPopup(new firebase.auth.FacebookAuthProvider()).catch(err => {
  // User's email already exists.
  if (err.code === 'auth/account-exists-with-different-credential') {
    // The pending Facebook credential.
    var pendingCred = err.credential;
    // The provider account's email address.
    var email = err.email;
    // Get the sign-in methods for this email.
    auth.fetchSignInMethodsForEmail(email).then(methods => {
      // If the user has several sign-in methods, the first method
      // in the list will be the "recommended" method to use.
      if (methods[0] === 'password') {
        // TODO: Ask the user for their password.
        // In real scenario, you should handle this asynchronously.
        var password = promptUserForPassword();
        auth.signInWithEmailAndPassword(email, password).then(result => {
          return result.user.linkWithCredential(pendingCred);
        }).then(() => {
          // Facebook account successfully linked to the existing user.
          goToApp();
        });
        return;
      }
      // All other cases are external providers.
      // Construct provider object for that provider.
      // TODO: Implement getProviderForProviderId.
      var provider = getProviderForProviderId(methods[0]);
      // At this point, you should let the user know that they already have an
      // account with a different provider, and validate they want to sign in
      // with the new provider.
      // Note: Browsers usually block popups triggered asynchronously, so in
      // real app, you should ask the user to click on a "Continue" button
      // that will trigger signInWithPopup().
      auth.signInWithPopup(provider).then(result => {
        // Note: Identity Platform doesn't control the provider's sign-in
        // flow, so it's possible for the user to sign in with an account
        // with a different email from the first one.

        // Link the Facebook credential. We have access to the pending
        // credential, so we can directly call the link method.
        result.user.linkWithCredential(pendingCred).then(usercred => {
          // Success.
          goToApp();
        });
      });
    });
  }
});

O uso de um redirecionamento é semelhante a um pop-up, mas você precisa armazenar em cache a credencial pendente entre redirecionamentos de página (por exemplo, usando o armazenamento de sessão).

Alguns provedores, como o Google e a Microsoft, servem como provedores de e-mail e identidades sociais. Os provedores de e-mail são considerados autoritativos para todos os endereços relacionados ao domínio de e-mail hospedado. Isso significa que um usuário que fizer login com um endereço de e-mail hospedado pelo mesmo provedor nunca gerará esse erro (por exemplo, fazer login com o Google usando um @gmail.com e-mail ou Microsoft usando um @live.com, @outlook.com e-mail).

Como mesclar contas manualmente

Se um usuário tentar fazer login com credenciais que já estão vinculadas a outra conta de usuário usando o mesmo provedor, os métodos integrados do SDK do cliente para vinculação de contas falharão. Nessa situação, você precisará mesclar as contas manualmente e excluir a segunda conta. Exemplo:

JavaScript

// Sign in first account.
const result1 = await auth.signInWithCredential(cred1);
const user1 = result1.user;
// Try to link a credential that belongs to an existing account
try {
  await user1.linkWithCredential(cred2);
} catch (error) {
  // cred2 already exists so an error is thrown.
  const result2 = await auth.signInWithCredential(error.credential);
  const user2 = result2.user;
  // Merge the data.
  mergeData(user1, user2);
  // Delete one of the accounts, and try again.
  await user2.delete();
  // Linking now will work.
  await user1.linkWithCredential(result2.credential);
}

É possível desvincular um provedor da conta de um usuário. O usuário não poderá mais se autenticar com esse provedor.

Para desvincular um provedor, transmita o ID dele ao método unlink() no usuário. Você pode conseguir o ID da propriedade providerData.

JavaScript

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

A seguir