如何为 Firestore 身份验证格式化自定义令牌?

How to format custom token for Firestore authentication?

我使用以下方法登录 Google -

override fun onClick(view: View?) {
        when (view?.id) {
           ...


            R.id.google_login -> {
                val signInIntent: Intent = googleSignInClient.signInIntent
                startActivityForResult(signInIntent, GOOGLE_LOGIN_REQUEST_CODE)
            }
        }
    }



override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK || requestCode != GOOGLE_LOGIN_REQUEST_CODE) return
        val task: Task<GoogleSignInAccount> = GoogleSignIn.getSignedInAccountFromIntent(data)
        val account = task.getResult(ApiException::class.java)
        saveAccountData(account)
    }

    private fun saveAccountData(account: GoogleSignInAccount?) {
        if (account == null) {
            Toast.makeText(requireContext(), getString(R.string.login_fragment_null_account_error), Toast.LENGTH_SHORT).show()
            return
        }
        if (account.email == null) {
            Toast.makeText(requireContext(), getString(R.string.login_fragment_selected_account_has_no_email_error), Toast.LENGTH_LONG).show()
            return
        }
        // This method saves the data in my Firestore DB 
        viewmodel.registerUser(account).observeOnce(requireActivity(), Observer { error ->
            error?.let { message ->
                Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
                return@Observer
            }

            saveAccountToPrefs(account)

            navController.navigate(LoginFragmentDirections.actionLoginFragmentToTermsAndConditionsFragment(account.givenName!!))
        })
    }

private fun saveAccountToPrefs(account: GoogleSignInAccount) {
        profileSharedPrefs.edit {
            putString(USER_REGISTERED_ID, account.email)
            putString(USER_DISPLAY_NAME, account.displayName)
            putString(USER_TOKEN, account.id)
            putBoolean(DID_USER_REGISTER, true)
        }
    }

问题是,我的数据库有以下错误规则 -

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
    
      allow read, write: if true
    }
  }
}

并且我想添加如下所示的简单身份验证 -

// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

因此,当我使用 ID(这是用户的电子邮件)尝试像此处一样配置自定义令牌时,我总是收到错误消息 -

private fun authAndNavigate(directions : NavDirections) {
        auth.signInWithCustomToken(profileSharedPrefs.getString(USER_TOKEN, "")!!)
            .addOnCompleteListener { task ->
                if (task.isSuccessful) {
                    Toast.makeText(requireContext(), auth.currentUser.toString(), Toast.LENGTH_LONG).show()
                    navController.navigate(directions)
                } else {
                    Toast.makeText(requireContext(), "Authentication failed, please restart app", Toast.LENGTH_LONG).show()
                    return@addOnCompleteListener
                }
            }
            .addOnFailureListener { exception ->
                exception.localizedMessage?.let { message ->
                    Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show()
                }
            }
    }

我得到的错误是-

The custom token format is incorrect. Please check the documentation. [ Invalid assertion format. 3 dot-separated segments required. ]

我找不到任何示例来说明如何实际格式化我的 ID(这是一封电子邮件)的方式首先可以工作并且不会引发错误,然后再使用我想在我的项目中实施的规则。

您从 Google sign-in 返回的是一个 OAuth 凭据,您可以通过将这些凭据传递给 signInWithCredential 来使用它登录 Firebase,如第 4 步中所示signing in with Firebase with Google auth credentials.

上的此文档

您的代码调用 signInWithCustomToken,它需要一个自定义 JWT,由您 运行 在自己的可信环境中生成的代码生成,如 minting custom tokens 上的文档所示。

虽然这两种类型的令牌都可用于通过 Firebase 进行身份验证,但您不能在 API 调用中交换它们。