首页 > 解决方案 > 自定义 Firebase 身份验证:令牌格式不正确错误

问题描述

我正在尝试使用自定义登录来使用 google 登录登录 Firebase,但无法登录。firbase 抛出的错误是com.google.firebase.auth.FirebaseAuthInvalidCredentialsException:自定义令牌格式不正确。请检查文档。请注意令牌尚未过期。

我检查了 google post login 共享的 IdToken 但在 jwt.io 上是否正确读取?任何人都可以指导这个问题吗?使用 Google 的自定义登录,因为我需要 refrsh 令牌,因为我需要 google apis 来持续访问 apis... 通过代码如下:

class WelcomeActivity : AppCompatActivity() {

    var firebaseUser: FirebaseUser? = null
    //For Google Sign In
    val RC_SIGN_IN: Int = 9001
    private lateinit var mGoogleSignInClient: GoogleSignInClient
    lateinit var mGoogleSignInOptions: GoogleSignInOptions
    private lateinit var firebaseAuth: FirebaseAuth
    private var firebaseUserID : String = ""
    private lateinit var refUsers : DatabaseReference

    //get data from google signin
    private var googleId  = ""
    private var googleFirstName = ""
    private var googleLastName = ""
    private var googleEmail = ""
    private var googleProfilePicURL = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_welcome)

    //        //For google sign in
    //        configureGoogleSignIn()
    //        setupUI()
        firebaseAuth = FirebaseAuth.getInstance()

        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken("896894788293-oe0enptjj2hltdde9isemuf89gtkb7u4.apps.googleusercontent.com")
            .requestEmail()
            .build()

        mGoogleSignInClient = GoogleSignIn.getClient(this, gso)

        google_login.setOnClickListener {
            signIn()
        }

        signup_welcome.setOnClickListener {
            val intent = Intent(this@WelcomeActivity, RegisterActivity::class.java)
            startActivity(intent)
            finish()
        }
        login_welcome.setOnClickListener {
            val intent = Intent(this@WelcomeActivity, LoginActivity::class.java)
            startActivity(intent)
            finish()
        }
    }

    private fun signIn() {
        val signInIntent = mGoogleSignInClient.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RC_SIGN_IN) {
            val task =
                GoogleSignIn.getSignedInAccountFromIntent(data)
                handleSignInResult(task)
        }
    }

    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
        try {
            val account = completedTask.getResult(
                ApiException::class.java
            )
            // Signed in successfully
            googleId = account?.id ?: ""
            Log.i("Google ID", googleId)

            googleFirstName = account?.givenName ?: ""
            Log.i("Google First Name", googleFirstName)

            googleLastName = account?.familyName ?: ""
            Log.i("Google Last Name", googleLastName)

            googleEmail = account?.email ?: ""
            Log.i("Google Email", googleEmail)

            val googleIdToken: String = account?.idToken ?: ""
            Log.i("Google ID Token", googleIdToken)

            googleProfilePicURL = account?.photoUrl.toString()
            Log.i("Google Profile Pic URL", googleProfilePicURL)

            val googleAccessToken = account?.serverAuthCode ?: ""
            Log.i("Google Server Auth Code", googleAccessToken)

            firebaseLogIn(googleIdToken)


        } catch (e: ApiException) {
            // Sign in was unsuccessful
            Log.e("failed code=", e.statusCode.toString()
            )
        }
    }

    private fun firebaseLogIn(customToken: String) {
        customToken.let {
            firebaseAuth.signInWithCustomToken(it)
                .addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCustomToken:success")
                        firebaseUserID = firebaseAuth.currentUser!!.uid

                        val intent = Intent(
                                        this@WelcomeActivity,
                                        IntroSplashScreen::class.java
                                    )
                                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                                    startActivity(intent)
                                    finish()

    //                        //saving the details of a new user to the firebase database
                            refUsers = FirebaseDatabase.getInstance().reference.child("Users").child(
                                firebaseUserID
                            )
                        val usersHashMap = HashMap<String, Any>()
                        usersHashMap["uid"] = firebaseUserID

                        refUsers.updateChildren(usersHashMap)
                            .addOnCompleteListener{
                                if(task.isSuccessful){
                                    val intent = Intent(
                                        this@WelcomeActivity,
                                        IntroSplashScreen::class.java
                                    )
                                    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                                    startActivity(intent)
                                    finish()
                                }

                            }
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "signInWithCustomToken:failure", task.exception)
                        Toast.makeText(
                            baseContext, "Authentication failed.",
                            Toast.LENGTH_SHORT
                        ).show()

                    }
                }
        }
    }

    override fun onStart() {
        super.onStart()
        //Checks if user is logged in
        firebaseUser = FirebaseAuth.getInstance().currentUser
        //If logged in then sends to MainActivity
        if(firebaseUser!=null){
            startActivity(IntroSplashScreen.getLaunchIntent(this))
            finish()
        }
    }
}

标签: androidkotlinfirebase-authentication

解决方案


signInWithCustomToken不支持您使用的方式。这仅在您实现自己的身份验证提供程序时使用,如文档中所述。您不能从其他身份验证系统传递令牌(包括 Google 身份验证,就像您在此处所做的那样)。您只能使用 Firebase Admin SDK 传递您在自己的后端创建的令牌。

如果你想使用谷歌登录,你应该按照文档进行操作。您将signInWithCredential改为使用。


推荐阅读