Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

Свяжите несколько поставщиков аутентификации с учетной записью с помощью JavaScript

Вы можете разрешить пользователям входить в ваше приложение с помощью нескольких поставщиков аутентификации, связав учетные данные поставщика аутентификации с существующей учетной записью пользователя. Пользователи идентифицируются по одному и тому же идентификатору пользователя Firebase независимо от поставщика аутентификации, который они использовали для входа. Например, пользователь, который вошел в систему с паролем, может связать учетную запись Google и войти в систему любым методом в будущем. Или анонимный пользователь может связать учетную запись Facebook, а затем войти в систему с помощью Facebook, чтобы продолжить использование вашего приложения.

Прежде чем вы начнете

Добавьте в свое приложение поддержку двух или более провайдеров аутентификации (возможно, включая анонимную аутентификацию).

Чтобы связать учетные данные от поставщика аутентификации, такого как Google или Facebook, с существующей учетной записью пользователя:

  1. Войдите в систему, используя любой провайдер или метод аутентификации.
  2. Получить AuthProvider объект , который соответствует поставщику вы хотите ссылку на счет пользователя. Примеры:

    Веб-версия 9

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

    Веб-версия 8

    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. Предложите пользователю войти в систему с провайдером, которого вы хотите связать. Вы можете предложить своим пользователям войти в систему, открыв всплывающее окно или перенаправив на страницу входа поставщика. На мобильных устройствах предпочтительнее использовать метод перенаправления.
    • Для того, чтобы войти в всплывающем окне, вызов linkWithPopup :

      Веб-версия 9

      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.
        // ...
      });

      Веб-версия 8

      auth.currentUser.linkWithPopup(provider).then((result) => {
        // Accounts successfully linked.
        var credential = result.credential;
        var user = result.user;
        // ...
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    • Для того, чтобы войти в систему , чтобы перенаправлять провайдера страницы входа, вызов linkWithRedirect :

      Веб-версия 9

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

      Веб-версия 8

      auth.currentUser.linkWithRedirect(provider)
        .then(/* ... */)
        .catch(/* ... */);
      После того, как пользователь войдет в систему, он будет перенаправлен обратно на вашу страницу. Затем, вы можете получить вход в результате по телефону getRedirectResult когда страница загружается:

      Веб-версия 9

      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.
        // ...
      });

      Веб-версия 8

      auth.getRedirectResult().then((result) => {
        if (result.credential) {
          // Accounts successfully linked.
          var credential = result.credential;
          var user = result.user;
          // ...
        }
      }).catch((error) => {
        // Handle Errors here.
        // ...
      });
    Если пользователь успешно вошел в систему, учетная запись пользователя у поставщика будет связана с учетной записью пользователя в вашем проекте Firebase.

    Связь учетной записи не удастся, если учетные данные уже связаны с другой учетной записью пользователя. В этой ситуации вы должны обработать объединение учетных записей и связанных данных в соответствии с вашим приложением:

    Веб-версия 9

    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);
    });

    Веб-версия 8

    // 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);
    });

Чтобы добавить учетные данные адреса электронной почты и пароля к существующей учетной записи пользователя:

  1. Войдите в систему, используя любой провайдер или метод аутентификации.
  2. Запрашивать у пользователя адрес электронной почты и новый пароль.
  3. Создать AuthCredential объект с помощью адреса электронной почты и пароля:

    Веб-версия 9

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

    Веб-версия 8

    var credential = firebase.auth.EmailAuthProvider.credential(email, password);
  4. Пропустите AuthCredential объект на зарегистрированны пользователя linkWithCredential метода:

    Веб-версия 9

    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);
      });

    Веб-версия 8

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

    Вызов linkWithCredential потерпит неудачу , если учетные данные уже связаны с другой учетной записью пользователя. В этой ситуации вы должны обработать объединение учетных записей и связанных данных в соответствии с вашим приложением (см. Пример выше).

Вы можете отключить поставщика аутентификации от учетной записи, чтобы пользователь больше не мог входить в систему с этим поставщиком.

Для того, чтобы разъединить поставщик аутентификации с учетной записью пользователя, передать идентификатор поставщика к unlink метода. Вы можете получить идентификаторы провайдера провайдеров AUTH , связанных с пользователем из providerData собственности.

Веб-версия 9

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

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

Веб-версия 8

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