同时实现账号密码与Google登录时应用崩溃问题排查
崩溃核心原因
从报错栈可以直接定位问题:
Caused by: java.lang.ClassCastException: com.google.android.gms.common.SignInButton cannot be cast to android.widget.Button
at com.example.shoppo.SignUpActivity.onCreate(SignUpActivity.kt:51)
布局中R.id.gSignInBtn是Google官方提供的SignInButton控件(属于com.google.android.gms.common包),但你在代码里强制将其转换为普通的android.widget.Button,触发了类型转换异常。
修复步骤
1. 修正类型转换错误
方案一:直接指定正确类型
修改SignUpActivity.kt中第51行的代码:
// 原代码 findViewById<Button>(R.id.gSignInBtn).setOnClickListener{ // 修改后 findViewById<com.google.android.gms.common.SignInButton>(R.id.gSignInBtn).setOnClickListener{
方案二:导入类后简化写法
在文件顶部的导入区添加:
import com.google.android.gms.common.SignInButton
然后修改代码为:
findViewById<SignInButton>(R.id.gSignInBtn).setOnClickListener{
2. 其他潜在问题修复(建议同步处理)
(1)初始化Firestore实例
代码中声明了private lateinit var db: FirebaseFirestore但未初始化,后续使用会触发未初始化异常,建议在onCreate中添加:
db = FirebaseFirestore.getInstance()
(2)修复函数作用域问题
你的signInWithGoogle和signInWithEmailPassword函数定义在了类外部,无法访问类内的auth、db等成员变量,需要将这两个函数移到SignUpActivity类内部:
class SignUpActivity : AppCompatActivity() { // ... 类内成员变量 ... override fun onCreate(savedInstanceState: Bundle?) { // ... onCreate代码 ... } // 移到类内部的登录函数 private fun signInWithGoogle(googleSignInAccount: GoogleSignInAccount) { // ... 原函数逻辑 ... } private fun signInWithEmailPassword(email: String, password: String) { // ... 原函数逻辑 ... } } // 类的闭合括号放在这里
(3)优化角色存储逻辑
当前用user?.displayName判断角色(buyer/seller)不合理,displayName是用户昵称,不适合存储业务角色。建议在Firestore的用户文档中单独添加role字段,登录后从数据库读取:
// 替换原角色判断逻辑 db.collection("users").document(user?.uid!!).get() .addOnSuccessListener { document -> val role = document.getString("role") when(role) { "buyer" -> startActivity(Intent(this, BuyerActivity::class.java)) "seller" -> startActivity(Intent(this, SellerActivity::class.java)) else -> startActivity(Intent(this, RegistrationActivity::class.java)) } }
验证修复
完成上述修改后重新编译运行,崩溃问题即可解决。同时建议测试两种登录方式的互斥规则(Google注册用户无法用密码登录,反之亦然),确保业务逻辑正常。
内容的提问来源于stack exchange,提问作者Ajay Satpati

