您可以允許用戶使用多個身份驗證提供程序登錄您的應用程序,方法是將身份驗證提供程序憑據鏈接到現有用戶帳戶。用戶可以通過相同的 Firebase 用戶 ID 進行識別,而不管他們用於登錄的身份驗證提供程序如何。例如,使用密碼登錄的用戶可以關聯 Google 帳戶並在未來使用任一方法登錄。或者,匿名用戶可以鏈接 Facebook 帳戶,然後使用 Facebook 登錄以繼續使用您的應用程序。
在你開始之前
向您的應用程序添加對兩個或更多身份驗證提供程序(可能包括匿名身份驗證)的支持。
將聯合身份驗證提供程序憑據鏈接到用戶帳戶
要將來自 Google 或 Facebook 等身份驗證提供商的憑據鏈接到現有用戶帳戶:
- 使用任何身份驗證提供程序或方法登錄用戶。
- 獲取與您要鏈接到用戶帳戶的提供商相對應的
AuthProvider
對象。例子: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();
- 提示用戶使用您要鏈接的提供商登錄。您可以通過打開彈出窗口或重定向到提供商的登錄頁面來提示您的用戶登錄。在移動設備上首選重定向方法。
- 要使用彈出窗口登錄,請調用
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. // ... });
- 要通過重定向到提供商的登錄頁面進行登錄,請調用
linkWithRedirect
:在使用 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(/* ... */);
getRedirectResult
來檢索登錄結果: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. // ... });
如果憑據已鏈接到另一個用戶帳戶,則帳戶鏈接將失敗。在這種情況下,您必鬚根據您的應用程序處理合併帳戶和關聯數據:
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); });
- 要使用彈出窗口登錄,請調用
將電子郵件地址和密碼憑據鏈接到用戶帳戶
將電子郵件地址和密碼憑據添加到現有用戶帳戶:
- 使用任何身份驗證提供程序或方法登錄用戶。
- 提示用戶輸入電子郵件地址和新密碼。
- 使用電子郵件地址和密碼創建
AuthCredential
對象: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);
將
AuthCredential
對像傳遞給登錄用戶的linkWithCredential
方法: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); });
如果憑據已鏈接到另一個用戶帳戶,則對
linkWithCredential
的調用將失敗。在這種情況下,您必鬚根據您的應用程序處理合併帳戶和關聯數據(請參見上面的示例)。
從用戶帳戶取消鏈接身份驗證提供程序
您可以取消身份驗證提供程序與帳戶的鏈接,以便用戶無法再使用該提供程序登錄。
要取消身份驗證提供程序與用戶帳戶的鏈接,請將提供程序 ID 傳遞給unlink
方法。您可以從providerData
屬性獲取鏈接到用戶的身份驗證提供程序的提供程序 ID。
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 // ... });