Android Studio多用户级别登录:跳转对应Activity问题及代码优化
问题分析与解决方案
一、user_lvl 为空的核心原因
Firebase Realtime Database的addListenerForSingleValueEvent是异步操作——你调用getUserData后立刻执行了if(user_lvl.equals(...))的判断逻辑,但此时回调onResponse还未触发,user_lvl仍处于未赋值状态(甚至会因lateinit未初始化抛出异常),这就是跳转逻辑失效的根本原因。
二、修复跳转逻辑的关键调整
必须将页面跳转逻辑放到Firebase回调的onResponse方法内部,确保拿到用户级别后再执行跳转:
firebaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener { task -> if (task.isSuccessful) { getUserData(object : FirebaseCallback { override fun onUserLoaded(user: User?) { val userLevel = user?.Livello ?: "" when(userLevel) { "1" -> startActivity(Intent(this@LoginActivity, MainActivity::class.java)) "2" -> startActivity(Intent(this@LoginActivity, EmployeeActivity::class.java)) "3" -> startActivity(Intent(this@LoginActivity, RestaurateurActivity::class.java)) else -> Toast.makeText(this@LoginActivity, "未知用户级别", Toast.LENGTH_LONG).show() } Toast.makeText(this@LoginActivity, "登录成功!", Toast.LENGTH_LONG).show() } }) } else { // 登录失败时显示具体错误信息,而非笼统提示 Toast.makeText(this@LoginActivity, task.exception?.message ?: "登录失败", Toast.LENGTH_LONG).show() } }
三、代码优化全方案
1. 变量与命名规范
- 遵循Kotlin驼峰命名法:
Email→email、Password→password、user_lvl→userLevel - 全局初始化Firebase实例:
firebaseAuth和firebaseDatabase在onCreate中初始化一次即可,无需在getUserData中重复初始化
2. 封装用户级别与跳转逻辑
用枚举类统一管理用户级别,避免硬编码字符串,同时封装跳转方法简化代码:
// 统一管理用户级别 enum class UserLevel(val value: String) { NORMAL("1"), EMPLOYEE("2"), RESTAURATEUR("3") } // 封装跳转逻辑 private fun navigateToHome(level: String) { val intent = when(level) { UserLevel.NORMAL.value -> Intent(this, MainActivity::class.java) UserLevel.EMPLOYEE.value -> Intent(this, EmployeeActivity::class.java) UserLevel.RESTAURATEUR.value -> Intent(this, RestaurateurActivity::class.java) else -> { Toast.makeText(this, "未知用户级别", Toast.LENGTH_LONG).show() return } } startActivity(intent) finish() // 登录成功后关闭当前页面,避免返回登录页 }
3. 简化Firebase回调逻辑
去掉冗余的Response数据类,直接返回User对象,同时利用Firebase自动序列化简化数据解析:
private interface FirebaseCallback { fun onUserLoaded(user: User?) } private fun getUserData(callback: FirebaseCallback) { val currentUser = firebaseAuth.currentUser ?: run { Toast.makeText(this, "未检测到登录用户", Toast.LENGTH_LONG).show() callback.onUserLoaded(null) return } firebaseDatabase.getReference("Utenti").child(currentUser.uid) .addListenerForSingleValueEvent(object : ValueEventListener { override fun onDataChange(snapshot: DataSnapshot) { // 直接用Firebase序列化User对象,需确保User类有默认无参构造函数 val user = snapshot.getValue(User::class.java) callback.onUserLoaded(user) } override fun onCancelled(error: DatabaseError) { Toast.makeText(this@LoginActivity, "数据加载失败: ${error.message}", Toast.LENGTH_LONG).show() callback.onUserLoaded(null) } }) }
注意:要让Firebase自动序列化
User类,需确保类有无参构造函数,且字段名与数据库键名完全匹配(可通过@PropertyName注解映射不一致的字段)
4. 完善onStart逻辑
原onStart直接跳转MainActivity忽略用户级别,修复为获取级别后再跳转:
override fun onStart() { super.onStart() firebaseAuth.currentUser?.let { getUserData(object : FirebaseCallback { override fun onUserLoaded(user: User?) { user?.Livello?.let { level -> navigateToHome(level) } ?: Toast.makeText(this@LoginActivity, "用户数据加载失败", Toast.LENGTH_LONG).show() } }) } }
5. 清理冗余代码
- 删除全局
lateinit var user_lvl: String,改用局部变量在回调中使用 - 简化按钮点击事件语法:
binding.ConstraintEntra.setOnClickListener { ... }(移除多余括号)
四、优化后的完整代码
package com.example.progettoprogrammazione.activity import android.content.Intent import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.example.progettoprogrammazione.databinding.ActivityLoginBinding import com.example.progettoprogrammazione.models.User import com.google.firebase.auth.FirebaseAuth import com.google.firebase.database.DataSnapshot import com.google.firebase.database.DatabaseError import com.google.firebase.database.FirebaseDatabase import com.google.firebase.database.ValueEventListener // 统一管理用户级别枚举 enum class UserLevel(val value: String) { NORMAL("1"), EMPLOYEE("2"), RESTAURATEUR("3") } class LoginActivity : AppCompatActivity() { private lateinit var binding: ActivityLoginBinding private lateinit var firebaseAuth: FirebaseAuth private lateinit var firebaseDatabase: FirebaseDatabase override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityLoginBinding.inflate(layoutInflater) setContentView(binding.root) // 全局初始化Firebase实例 firebaseAuth = FirebaseAuth.getInstance() firebaseDatabase = FirebaseDatabase.getInstance() // 登录按钮点击事件 binding.ConstraintEntra.setOnClickListener { val email = binding.email.text.toString().trim() val password = binding.password.text.toString().trim() if (email.isNotEmpty() && password.isNotEmpty()) { firebaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener { task -> if (task.isSuccessful) { getUserData(object : FirebaseCallback { override fun onUserLoaded(user: User?) { user?.Livello?.let { level -> navigateToHome(level) Toast.makeText(this@LoginActivity, "登录成功!", Toast.LENGTH_LONG).show() } ?: Toast.makeText(this@LoginActivity, "用户数据异常", Toast.LENGTH_LONG).show() } }) } else { Toast.makeText(this@LoginActivity, task.exception?.message ?: "登录失败", Toast.LENGTH_LONG).show() } } } else { Toast.makeText(this, "所有字段不能为空!", Toast.LENGTH_LONG).show() } } // 跳转注册页面 binding.noaccount.setOnClickListener { startActivity(Intent(this, RegisterActivity::class.java)) } } override fun onStart() { super.onStart() // 已登录用户自动跳转对应主页 firebaseAuth.currentUser?.let { getUserData(object : FirebaseCallback { override fun onUserLoaded(user: User?) { user?.Livello?.let { level -> navigateToHome(level) } ?: Toast.makeText(this@LoginActivity, "用户数据加载失败", Toast.LENGTH_LONG).show() } }) } } // Firebase数据回调接口 private interface FirebaseCallback { fun onUserLoaded(user: User?) } // 获取用户数据 private fun getUserData(callback: FirebaseCallback) { val currentUser = firebaseAuth.currentUser ?: run { Toast.makeText(this, "未检测到登录用户", Toast.LENGTH_LONG).show() callback.onUserLoaded(null) return } firebaseDatabase.getReference("Utenti").child(currentUser.uid) .addListenerForSingleValueEvent(object : ValueEventListener { override fun onDataChange(snapshot: DataSnapshot) { val user = snapshot.getValue(User::class.java) callback.onUserLoaded(user) } override fun onCancelled(error: DatabaseError) { Toast.makeText(this@LoginActivity, "数据加载失败: ${error.message}", Toast.LENGTH_LONG).show() callback.onUserLoaded(null) } }) } // 跳转对应主页 private fun navigateToHome(level: String) { val intent = when(level) { UserLevel.NORMAL.value -> Intent(this, MainActivity::class.java) UserLevel.EMPLOYEE.value -> Intent(this, EmployeeActivity::class.java) UserLevel.RESTAURATEUR.value -> Intent(this, RestaurateurActivity::class.java) else -> { Toast.makeText(this, "未知用户级别", Toast.LENGTH_LONG).show() return } } startActivity(intent) finish() } }
内容的提问来源于stack exchange,提问作者Steposkrt
相关产品推荐
相关产品推荐

