You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Firestore认证格式化自定义令牌?Google登录遇格式错误

问题根源分析

你遇到的错误核心是混淆了Google Sign-In用户ID和Firebase自定义令牌的本质:Firebase的signInWithCustomToken要求传入的是由Firebase Admin SDK生成的JWT格式令牌(三段式、点分隔结构),但你传入的是Google账号的ID(account.id),这完全不符合自定义令牌的格式规范,所以触发了格式错误提示。

而且你其实根本不需要用自定义令牌——你已经通过Google完成了登录,直接把Google登录的凭据关联到Firebase Auth即可,这样就能让Firestore规则识别到已登录用户。


正确实现步骤

1. 修改Google登录后的Firebase Auth关联逻辑

在你的saveAccountData方法中,添加Firebase Google认证的步骤,替换掉错误的自定义令牌登录逻辑:

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
    }

    // 新增:获取Google登录的Auth凭据并关联到Firebase Auth
    val credential = GoogleAuthProvider.getCredential(account.idToken, null)
    auth.signInWithCredential(credential)
        .addOnCompleteListener { authTask ->
            if (authTask.isSuccessful) {
                // 认证成功后,执行原有数据库操作和页面跳转逻辑
                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!!))
                })
            } else {
                Toast.makeText(requireContext(), "Firebase认证失败: ${authTask.exception?.localizedMessage}", Toast.LENGTH_LONG).show()
            }
        }
}

2. 移除错误的自定义令牌登录方法

你之前写的authAndNavigate方法可以直接删除,因为现在通过signInWithCredential已经完成了Firebase Auth的登录,后续Firestore规则会自动识别request.auth的存在。

3. 确认Firestore规则的正确性

你编写的规则是完全正确的,只要用户通过Firebase Auth完成登录,request.auth != null就会成立,用户就能正常读写数据库:

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

关于自定义令牌的澄清

自定义令牌是给非Firebase官方登录方式(比如你自己搭建的用户系统)使用的,必须在你的后端服务器上用Firebase Admin SDK生成,客户端不能直接生成。完整流程是:

  • 后端验证用户在自有系统中的身份
  • 后端用Admin SDK生成包含用户UID等信息的自定义令牌
  • 后端将令牌返回给客户端
  • 客户端调用signInWithCustomToken完成登录

而你使用的是Google登录,属于Firebase官方支持的登录方式,直接用signInWithCredential关联即可,完全不需要自定义令牌。

内容的提问来源于stack exchange,提问作者Alon Shlider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:08:13