android - 自定义 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()
}
}
}
解决方案
signInWithCustomToken
不支持您使用的方式。这仅在您实现自己的身份验证提供程序时使用,如文档中所述。您不能从其他身份验证系统传递令牌(包括 Google 身份验证,就像您在此处所做的那样)。您只能使用 Firebase Admin SDK 传递您在自己的后端创建的令牌。
如果你想使用谷歌登录,你应该按照文档进行操作。您将signInWithCredential
改为使用。
推荐阅读
- jenkins - 如何获取删除了几个 Jenkins 作业版本的用户的详细信息?
- java - Apache Tomcat:源服务器没有找到目标资源的当前表示或不愿意透露
- blazor - Blazor 服务器端和单独项目中的模块
- jasny-bootstrap - Jasny 文件上传postedfile 始终为空
- jquery - 在codeigniter中计算jquery ajax中的值
- python - 为什么正则表达式带有“|” (或/替代)顺序切换时匹配不同?
- javascript - Open a different URL in the same window
- ios - 通过 hockey(App Center)或 Fabric 共享时,分布式构建的有效期是多久?
- pdf - 我需要在我的谷歌驱动器中显示一个 pdf 作为缩略图,在谷歌表中..如何使用谷歌脚本?
- javascript - 无法让数据列表在所有浏览器中自动完成。此外,它仅适用于 MS edge 中所需的“startswith”模式