[英]Check if Firebase Facebook user exists without creating a user starting from anonymous user
在Firebase中,我需要檢查Facebook用戶是否存在而不創建該用戶。 最初,用戶是匿名的,他們嘗試使用Facebook登錄。 如果Facebook帳戶尚未鏈接到我的系統中的用戶,我希望此操作失敗。 它不會鏈接到當前用戶,因為他們是匿名用戶,
如果我使用Auth.signInAndRetrieveDataWithCredential,則可能會出現“ auth / user-not-found ”錯誤,但是只是創建了用戶。 這是錯誤還是預期的?
let credential = firebase.auth.FacebookAuthProvider.credential(
event.authResponse.accessToken)
firebase.auth().signInAndRetrieveDataWithCredential(credential).then( (userCredential) => {
let user = userCredential.user
app.debug("DEBUG: Existing user signed in:"+user.uid)
this.loginSuccess(user)
}).catch( (err) => {
app.error("ERROR re-signing in:"+err.code)
$("#login_status_msg").text(err)
})
如果我使用User.reauthenticateAndRetrieveDataWithCredential,則會收到錯誤“ auth / user-mismatch ”,這很有意義,因為用戶當前是匿名用戶。 但是,我期望如果憑據不存在,則可能會拋出“ auth / user-not-found”,但這不會發生。
我沒有找到一種方法來吸引我的匿名用戶,讓他們使用Facebook登錄,然后查看是否有另一個用戶已鏈接到該Facebook憑據,而無需創建該用戶(如果該用戶不存在)。
如果您想知道為什么? 我的情況是:系統允許匿名用戶
我找到了解決方案! 實施起來並不難,但是看起來確實很hack。
因此我們知道,在使用signInAndRetrieveDataWithCredential(cred)
進行Facebook登錄時, 即使該帳戶尚不存在 ,也會創建該帳戶。 為了解決這個問題,我們需要確保處理以下三件事:
我剛剛實現並測試了該解決方案,它看起來很棒:
// ... do your stuff to do fb login, get credential, etc:
const userInfo = await firebase.auth().signInAndRetrieveDataWithCredential(credential)
// userInfo includes a property to check if the account is new:
const isNewUser = _.get(userInfo, 'additionalUserInfo.isNewUser', true)
// FIRST, delete the account we just made.
// SECOND, throw an error (or otherwise escape the current context.
if (isNewUser) {
firebase.auth().currentUser.delete()
throw new Error('Couldn\'t find an existing account.')
}
// If the user already exists, just handle normal login
return userInfo.user
我這樣做的原因是為了確保用戶必須通過我的應用程序中的“創建帳戶流程”。 您的案例也很容易實現,如下所示:
let credential = firebase.auth.FacebookAuthProvider.credential(event.authResponse.accessToken)
firebase.auth().signInAndRetrieveDataWithCredential(credential)
.then(userCredential => {
const isNewUser = userCredential.additionalUserInfo.isNewUser
if (isNewUser) {
firebase.auth().currentUser.delete()
// The following error will be handled in your catch statement
throw new Error("Couldn't find an existing account.")
}
// Otherwise, handle login normally:
const user = userCredential.user
app.debug("DEBUG: Existing user signed in:"+user.uid)
this.loginSuccess(user)
}).catch( (err) => {
app.error("ERROR re-signing in:"+err.code)
$("#login_status_msg").text(err)
})
您可以使用方法fetchSignInMethodsForEmail
來檢查特定的電子郵件是否已經與特定的提供者相關聯。 這樣做,您將能夠檢查與您的用戶關聯的電子郵件的SighInMethods
是否包含Facebook.com
。
我在下面的示例中向您展示了如何在應用程序中管理這種情況。 我在代碼上使用RxJavaWrapper,但是您將了解如何管理它的要點:
RxFirebaseAuth.fetchSignInMethodsForEmail(authInstance, email)
.flatMap { providerResult ->
if (!providerResult.signInMethods!!.contains(credential.provider)) {
return@flatMap Maybe.error<AuthResult>(ProviderNotLinkedException(credential.provider))
} else {
return@flatMap RxFirebaseAuth.signInWithCredential(authInstance, credential)
}
}
.subscribe({ authResult ->
//Manage success
}, { error ->
//Manage error
})
signInWithCredential
方法來創建用戶。 您可以使用linkAndRetrieveDataWithCredential
:
let credential = firebase.auth.FacebookAuthProvider.credential(
event.authResponse.accessToken);
anonymousUser.linkAndRetrieveDataWithCredential(credential).then( (userCredential) => {
// Firebase Auth only allows linking a credential if it is not
// already linked to another account.
// Now the anonymous account is upgraded to a permanent Facebook account.
}).catch( (err) => {
// Check for code: auth/credential-already-in-use
// When this error is returned, it means the credential is already
// used by another account.
})
為了解決此問題,而又不依賴於對linkAndRetrieveDataWithCredential
的調用失敗並使用catch塊登錄已存在的用戶的問題,我linkAndRetrieveDataWithCredential
是保存getCurrentAccessToken
返回的userID
字段。
const { userID } = data;
this.props.setFacebookId(userID); // saves the userID on the server
稍后我可以在下次用戶注冊Facebook時檢查該userID
已經存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.