您可以將驗證供應商憑證連結至現有使用者帳戶,允許使用者透過多個驗證供應商登入應用程式。無論使用者透過哪個驗證提供者登入,系統都會使用相同的 Firebase 使用者 ID 識別使用者。舉例來說,以密碼登入的使用者可以連結 Google 帳戶,日後就能透過任一方法登入。或者,匿名使用者可以連結 Facebook 帳戶,然後稍後使用 Facebook 登入,繼續使用您的應用程式。
事前準備
在應用程式中新增對兩個以上驗證供應商的支援 (可能包括匿名驗證)。
將聯合驗證供應商憑證連結至使用者帳戶
如要將 Google 或 Facebook 等驗證供應商的憑證連結至現有使用者帳戶,請按照下列步驟操作:
- 使用任何驗證供應商或方法登入使用者。
- 取得與您要連結至使用者帳戶的供應商相應的
AuthProvider
物件。範例: <0x0AWeb
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
的呼叫就會失敗。在這種情況下,您必須視應用程式需求,處理帳戶和相關聯資料的合併作業 (請參閱上例)。
取消連結使用者帳戶與驗證服務供應商
您可以取消驗證供應商與帳戶的連結,這樣使用者就無法再透過該供應商登入。
如要取消授權提供者與使用者帳戶的連結,請將提供者 ID 傳遞至 unlink
方法。您可以從 providerData
屬性取得連結至使用者的驗證提供者 ID。
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 // ... });
疑難排解
如果嘗試連結多個帳戶時發生錯誤,請參閱已驗證電子郵件地址的說明文件。