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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:40:35