我正在关注Firebase关于社交登录的说明。下面是我正在使用的一个示例,它从登录身份验证的角度来看都很好。
然而,我有谷歌和Facebook登录独立工作。我现在想要做的是链接帐户。您可以在下面看到这可能发生的地方(查看评论):
如果您在应用中使用多个身份验证提供程序,则应在此处理用户帐户的链接。
我尝试了很多我认为应该去的地方,但无济于事。谁能引导我关于他们认为应该去哪里?谢谢!
function initFBApp() {
// Result from Redirect auth flow.
// [START getidptoken]
firebase.auth().getRedirectResult().then(function (result) {
if (result.credential) {
// This gives you a Facebook Access Token. You can use it to access the Facebook API.
var token = result.credential.accessToken;
// [START_EXCLUDE]
document.getElementById('FBquickstart-oauthtoken').textContent = token;
}
else {
document.getElementById('FBquickstart-oauthtoken').textContent = 'null';
// [END_EXCLUDE]
}
// The signed-in user info.
var user = result.user;
}).catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// [START_EXCLUDE]
if (errorCode === 'auth/account-exists-with-different-credential') {
alert('You have already signed up with a different auth provider for that emails.');
// If you are using multiple auth providers on your app you should handle linking
// the user's accounts here.
}
else {
console.error(error);
}
// [END_EXCLUDE]
});
// [END getidptoken]
// Listening for auth state changes.
// [START authstatelistener]
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
// User is signed in.
var displayName = user.displayName;
var email = user.email;
var emailVerified = user.emailVerified;
var photoURL = user.photoURL;
var isAnonymous = user.isAnonymous;
var uid = user.uid;
var providerData = user.providerData;
// [START_EXCLUDE]
document.getElementById('FBquickstart-sign-in-status').textContent = 'Signed in';
document.getElementById('FBquickstart-sign-in').textContent = 'Log out';
document.getElementById('FBquickstart-account-details').textContent = JSON.stringify(user, null, ' ');
// [END_EXCLUDE]
}
else {
// User is signed out.
// [START_EXCLUDE]
document.getElementById('FBquickstart-sign-in-status').textContent = 'Signed out';
document.getElementById('FBquickstart-sign-in').textContent = 'Log in with Facebook';
document.getElementById('FBquickstart-account-details').textContent = 'null';
document.getElementById('FBquickstart-oauthtoken').textContent = 'null';
// [END_EXCLUDE]
}
// [START_EXCLUDE]
document.getElementById('FBquickstart-sign-in').disabled = false;
// [END_EXCLUDE]
});
// [END authstatelistener]
document.getElementById('FBquickstart-sign-in').addEventListener('click', toggleFBSignIn, false);
}
答案 0 :(得分:3)
这些大致是关于如何处理auth / account-exists-with-different-credential的步骤: 如果您要登录使用已存在的其他帐户的电子邮件的新Facebook帐户,您将收到该错误。假设现有帐户是Google帐户。
您将在getRedirectResult().catch(function(error) {})
错误还将包含电子邮件和凭据字段。 您需要保存凭证(使用推荐的sessionStorage)。查看这篇文章了解更多信息: Firebase Authentication Javascript: setCookie for pending Credential for redirect
然后,您可以致电firebase.auth().fetchProvidersForEmail(error.email)
以确定该电子邮件已存在的提供商。
然后,您将登录其中一个现有提供商,并断言该电子邮件与error.email相同。成功后,您将从sessionStorage加载待定凭证,按照其他帖子中的描述重新初始化并将其链接到currentUser:
firebase.auth().currentUser.linkWithCredential(savedCred);
现在,您将同时关联两个帐户。请记住,现有提供程序可以是密码类型。在这种情况下,您不需要保存凭据,只需要询问用户密码并使用相同的电子邮件error.email对其进行签名。然后,您可以直接使用error.credential调用链接。
顺便说一句,我推荐firebaseui-web为您解决所有这些问题: https://github.com/firebase/firebaseui-web答案 1 :(得分:1)
我认为Firebase API changed a bit和firebase.auth().currentUser.link(savedCred);
现在是firebase.auth().currentUser.linkWithRedirect(provider)
。在我的实现中,我将最初选择的提供程序保存到sessionStorage,并在需要帐户链接时使用上述方法。
如果更符合您的需求,您也可以linkWithPopUp
。
答案 2 :(得分:1)
仔细阅读示例https://firebase.google.com/docs/auth/web/google-signin 部分“处理存在不同凭证错误的帐户”
重定向模式此错误在重定向中的处理方式相似 模式,区别在于必须缓存待处理的凭据 页面重定向之间(例如,使用会话存储)。
答案 3 :(得分:0)
下面是工作代码的相关代码段(位于异步函数内)。请注意,“苹果”只是Firestore中代表购物车的简化测试记录。
if(error.code === "auth/email-already-in-use"){
// REMEMBER AUTH CURRENT USER OBJECT
previousUser = firebase.auth().currentUser;
// WE MUST HANDLE DB READ AND DELETE WHILE SIGNED IN AS PREVIOUS USER PER FIRESTORE SECURITY RULES
if(localUserDoc){ //this was saved from .snapshot firing
if(localUserDoc.data().apples){
apples = localUserDoc.data().apples;
}
}
//DELETE CURRENT USER RECORD WHILE STILL SIGNED IN
await firebase.firestore().collection("users").doc(previousUser.uid).delete();
// CLEAN UP DONE. NOW SIGN IN USING EMAIL LINK CREDENTIAL
try {
var firebaseUserObj = await firebase.auth().signInAndRetrieveDataWithCredential(credential);
// FIRESTORE USER RECORD FOR EMAIL LINK USER WAS CREATED WHEN THEY ADDED APPLE TO CART
try {
var doc = await firebase.firestore().collection("users").doc(firebaseUserObj.user.uid).get();
if (doc.exists) {
if(doc.data().apples){
apples = apples + doc.data().apples;
}
}
await firebase.firestore().collection("users").doc(firebaseUserObj.user.uid).update({
apples: apples
});
} catch(error) {
console.log("Error getting document:", error);
}
previousUser.delete();
} catch (error) {
console.log(".signInWithCredential err ", error);
}
}