Вы можете разрешить пользователям входить в ваше приложение, используя несколько поставщиков аутентификации, связав учетные данные поставщика аутентификации с существующей учетной записью пользователя. Пользователи будут идентифицироваться по одному и тому же идентификатору пользователя Firebase независимо от того, какой поставщик аутентификации они использовали для входа. Например, пользователь, вошедший в систему с помощью пароля, может связать учетную запись Google и в дальнейшем входить в систему любым из этих способов. Или анонимный пользователь может связать учетную запись Facebook, а затем войти в систему через Facebook, чтобы продолжить использование вашего приложения.
Прежде чем начать
Добавьте в свое приложение поддержку двух или более поставщиков аутентификации (возможно, включая анонимную аутентификацию).
Привяжите учетные данные поставщика федеративной аутентификации к учетной записи пользователя.
Чтобы связать учетные данные от поставщика аутентификации, такого как Google или Facebook, с существующей учетной записью пользователя:
- Войдите в систему, используя любой поставщик или метод аутентификации.
- Получите объект
AuthProvider, соответствующий поставщику, который вы хотите связать с учетной записью пользователя. Примеры:Web
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
var googleProvider = new firebase.auth.GoogleAuthProvider(); var facebookProvider = new firebase.auth.FacebookAuthProvider(); var twitterProvider = new firebase.auth.TwitterAuthProvider(); var githubProvider = new firebase.auth.GithubAuthProvider();
- Предложите пользователю войти в систему у нужного вам провайдера. Вы можете сделать это, открыв всплывающее окно или перенаправив пользователя на страницу входа провайдера. На мобильных устройствах предпочтительнее использовать метод перенаправления.
- Для входа через всплывающее окно вызовите
linkWithPopup:Web
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
auth.currentUser.linkWithPopup(provider).then((result) => { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });
- Для входа в систему путем перенаправления на страницу входа провайдера вызовите метод
linkWithRedirect: следуйте рекомендациям по использованию `linkWithRedirect`.После авторизации пользователь перенаправляется обратно на вашу страницу. Затем вы можете получить результат авторизации, вызвавWeb
import { getAuth, linkWithRedirect, GoogleAuthProvider } from "firebase/auth"; const provider = new GoogleAuthProvider(); const auth = getAuth(); linkWithRedirect(auth.currentUser, provider) .then(/* ... */) .catch(/* ... */);
Web
auth.currentUser.linkWithRedirect(provider) .then(/* ... */) .catch(/* ... */);
getRedirectResultпри загрузке страницы:Web
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
auth.getRedirectResult().then((result) => { if (result.credential) { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... } }).catch((error) => { // Handle Errors here. // ... });
Связывание учетных записей не удастся, если учетные данные уже связаны с другой учетной записью пользователя. В этом случае необходимо выполнить объединение учетных записей и связанных с ними данных в соответствии с потребностями вашего приложения:
Web
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
// 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); });
- Для входа через всплывающее окно вызовите
Привяжите адрес электронной почты и пароль к учетной записи пользователя.
Чтобы добавить адрес электронной почты и пароль к существующей учетной записи пользователя:
- Войдите в систему, используя любой поставщик или метод аутентификации.
- Предложите пользователю ввести адрес электронной почты и новый пароль.
- Создайте объект
AuthCredential, содержащий адрес электронной почты и пароль:Web
import { EmailAuthProvider } from "firebase/auth"; const credential = EmailAuthProvider.credential(email, password);
Web
var credential = firebase.auth.EmailAuthProvider.credential(email, password);
Передайте объект
AuthCredentialв методlinkWithCredentialавторизованного пользователя:Web
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
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завершится ошибкой, если учетные данные уже связаны с другой учетной записью пользователя. В этом случае необходимо выполнить объединение учетных записей и связанных данных в соответствии с потребностями вашего приложения (см. пример выше).
Отменить привязку поставщика аутентификации к учетной записи пользователя.
К одной учетной записи пользователя Firebase можно привязать несколько поставщиков аутентификации (например, электронную почту/пароль, Google, Facebook), что позволяет пользователю входить в одну и ту же учетную запись Firebase разными способами.
Если вы отвяжете поставщика аутентификации от учетной записи пользователя, он больше не сможет войти в систему с помощью этого поставщика.
Чтобы отменить привязку поставщика аутентификации к учетной записи пользователя, передайте идентификатор поставщика методу unlink . Идентификаторы поставщиков аутентификации, связанных с пользователем, можно получить из свойства providerData .
Web
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
user.unlink(providerId).then(() => { // Auth provider unlinked from account // ... }).catch((error) => { // An error happened // ... });
Поиск неисправностей
Если при попытке связать несколько учетных записей возникают ошибки, обратитесь к документации по подтвержденным адресам электронной почты .