![](/img/trans.png)
[英]Flutter Firebase Auth + Firestore Provider user document
[英]Firebase: How to check if a user auth was overriden by another provider?
目前,我有四種不同的提供商方法可以在我的應用程序中登錄/創建帳戶:
當用戶第一次通過其中一個提供商登錄時(或通過 email 和密碼創建帳戶),我會自動在 cloud-firestore 中創建一個包含附加信息的用戶文檔。 我的其中一位提供商(電子郵件和密碼)出現了問題:
當用戶使用提供商“電子郵件和密碼”創建帳戶時,他可以選擇他/她喜歡的任何 email,因此也可以使用 Google 或 Microsoft email 並提供錯誤的附加信息(錯誤的名稱等)。 一旦用戶創建了他的帳戶,這個錯誤的信息就會存儲在我創建的用戶文檔中。
如果上述用戶隨后未驗證他的 email 並通過 Google 或 Microsoft 提供商登錄,舊的“電子郵件和密碼”提供商將被覆蓋,但不是我之前創建的錯誤用戶文檔。
我的問題是:有沒有辦法讓觀察者或知道一個提供者被另一個提供者覆蓋,因此也覆蓋了錯誤的用戶文檔?
// Check if user-document already exists, so it does not get overridden
// when logging in via Google, Microsoft or Facebook-auth
private suspend fun isUserRegistered(): Boolean {
val document = dbFirestore.collection(FIREBASE_USER_BASE_PATH).document(dbAuth.currentUser!!.uid).get().await()
return document.exists()
}
private suspend fun createUserIfNotExist(user: UserNetworkEntity) {
if (isUserRegistered()) return
createUserAccount(dbAuth.currentUser!!.uid, user)
}
// Function to check whether user is verified and delete old doc if not verified
// Here the user-data and the created user-doc will be verified via firebase-admin-sdk
private suspend fun callUserOnCheck(email: String): HttpsCallableResult? {
return dbFunctions
.getHttpsCallable(FUNCTION_USER_ON_CHECK_EMAIL)
.call(hashMapOf<String, String?>("email" to email))
.await()
}
override fun signInWithGoogle(account: GoogleSignInAccount): Flow<LoginStateEvent> = flow {
val credential = GoogleAuthProvider.getCredential(account.idToken, null)
// Delete old doc if not verified. Getting email from GoogleSignInAccount
// IMPORTANT: We have to check the old document here, before calling dbAuth.signInWithCredential()
// because #signInWithCredential() would override the old email-provider
val email = account.email!!
callUserOnCheck(email)
dbAuth.signInWithCredential(credential).await()
createUserIfNotExist(UserNetworkEntity(fullName = fullName))
}
override fun signInWithFacebook(): Flow<LoginStateEvent> = flow {
val result = fLoginManager.registerMCallback(callbackManager)
val credential = FacebookAuthProvider.getCredential(result.accessToken.token)
// Delete old doc if not verified. Getting email from Facebook-GraphResponse
// IMPORTANT: We have to check the old document here, before calling dbAuth.signInWithCredential()
// because #signInWithCredential() would override the old email-provider
callUserOnCheckFacebook(result.accessToken)
dbAuth.signInWithCredential(credential).await()
createUserIfNotExist(UserNetworkEntity(fullName = dbAuth.currentUser!!.displayName!!))
}
// Function to check whether user is verified. Special case: Get Facebook email via GraphResponce
private suspend fun callUserOnCheckFacebook(accessToken: AccessToken) {
val email = getFacebookEmail(accessToken)
if (email != null) callUserOnCheck(email)
}
// Get Facebook email via GraphResponce without the need to login via #signInWithCredential()
private suspend fun getFacebookEmail(accessToken: AccessToken) = suspendCancellableCoroutine<String?> { cont ->
val callback = GraphRequest.GraphJSONObjectCallback { json, response ->
// OnError
response?.error?.let { cont.resumeWithException(Throwable(it.errorMessage)) }
// OnSucess
cont.resume(json?.optString("email"), cont::resumeWithException)
}
GraphRequest.newMeRequest(accessToken, callback)
}
override fun signInWithMicrosoft(activity: Activity): Flow<LoginStateEvent> = flow {
// TODO: Check whether old created user-doc is valid or not before calling
// dbAuth.pendingAuthResult or ..startActivityForSignIn... as this would
// override the old existing email-provider.
// Question: How to get microsoft-email without calling #pendingAuthResult or #startActivityForSignIn ?
val result = dbAuth.pendingAuthResult?.await() ?: dbAuth.startActivityForSignInWithProvider(
activity,
microsoftOAuth.build()
).await()
createUserIfNotExist(UserNetworkEntity(fullName = result.user!!.displayName!!))
}
我認為您可能正在尋找fetchSignInMethodsForEmail
function 。 您可以將此傳遞給用戶的 email,然后檢查 email 是否已與電子郵件+密碼提供商一起使用(在這種情況下,您需要清理該文檔)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.