在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凭据而不创建用户(如果它不存在)。 / p>
如果你想知道为什么?我的情况是: 该系统允许匿名用户
答案 0 :(得分:1)
我找到了解决方案!实施起来并不难,但是看起来确实很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)
})
答案 1 :(得分:0)
您可以使用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
方法来创建用户。答案 2 :(得分:0)
You can use 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.
})
答案 3 :(得分:0)
我为解决此问题而没有依靠对@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=C:\Users\Test\Documents\Input" & rem // (absolute source path)
set "_TARGET=C:\Users\Test\Documents\Output" & rem // (absolute target path)
set "_PATTERN=*.*" & rem // (pure file pattern for input files)
set "_FILEEXT=.mp3" & rem // (pure file extension of output files)
pushd "%_TARGET%" || exit /B 1
for /F "delims=" %%F in ('
cd /D "%_SOURCE%" ^&^& ^(rem/ list but do not copy: ^
^& xcopy /L /S /Y /I ".\%_PATTERN%" "%_TARGET%" ^
^| find ".\" ^& rem/ remove summary line;
^)
') do (
2> nul mkdir "%%~dpF."
rem // Set up the correct `ffmpeg` command line here:
set "FFREPORT=file=C\:\\Users\\Test\\Documents\\Output\\ffreport-%%~F.log:level=32"
"C:\ffmpeg\bin\ffmpeg.exe" -report -n -i "%_SOURCE%\%%~F" -vn -c:a libmp3lame -b:a 128k "%%~dpnF%_FILEEXT%"
if not errorlevel 1 if exist "%%~dpnF%_FILEEXT%" del /f /q "%_SOURCE%\%%~F"
)
popd
endlocal
pause
的调用失败并且使用catch块登录已经存在的用户的方法是保存{{1} }返回。
linkAndRetrieveDataWithCredential
我以后可以在用户下次登录Facebook时检查此userID
是否已经存在。