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

Kotlin中Firebase数据库用户详情获取及页面崩溃问题求助

问题分析与解决方案

核心问题总结

  1. 初始化顺序错误:调用loadUserDetails()时,Firebase相关实例和UID还未初始化,触发空指针异常
  2. 重复跳转当前页面:点击个人资料导航按钮时重复启动User_Activity,引发栈异常
  3. 数据读取逻辑错误:错误遍历用户节点的子字段,无法正确获取用户数据
  4. 未处理未登录状态:未校验用户登录状态,无权限访问数据时触发异常跳转

分步修复方案

1. 调整初始化顺序

将loadUserDetails()移到Firebase实例、UID、数据库引用初始化完成之后,同时校验用户登录状态,未登录直接跳转登录页:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityUserBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // 先初始化Firebase并校验登录状态
    firebaseAuth = FirebaseAuth.getInstance()
    val currentUser = firebaseAuth.currentUser
    if (currentUser == null) {
        startActivity(Intent(this, MainActivity::class.java))
        finish()
        return
    }
    uid = currentUser.uid
    databaseReference = FirebaseDatabase.getInstance().getReference("Users")

    // 再加载用户数据
    loadUserDetails()

    // 其他按钮逻辑...
}

2. 修复导航栏跳转逻辑

点击个人资料按钮时,无需重复启动当前Activity,直接提示或忽略:

val gotoUser: ImageView = findViewById(R.id.navUser)
gotoUser.setOnClickListener {
    Toast.makeText(this, "已在个人资料页", Toast.LENGTH_SHORT).show()
}

3. 修正Firebase数据读取逻辑

根据你的数据库结构,Users节点下直接以用户UID为子节点,每个子节点包含email、username、id字段,无需遍历子节点,直接从快照读取:

private fun loadUserDetails() {
    val userRef = databaseReference.child(uid)

    userRef.addValueEventListener(object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            // 直接从用户节点快照读取字段,添加空值默认处理
            val email = snapshot.child("email").value?.toString() ?: "未知邮箱"
            val username = snapshot.child("username").value?.toString() ?: "未知用户名"
            val userId = snapshot.child("id").value?.toString() ?: "未知ID"

            binding.profileUID.text = userId
            binding.profileEmail.text = email
            binding.profileUsername.text = username
        }

        override fun onCancelled(error: DatabaseError) {
            Log.e("FirebaseError", "数据读取失败: ${error.message}")
        }
    })
}

4. 优化登出逻辑

调用Firebase登出方法并清除Activity栈,避免用户返回个人资料页:

val LogoutBtn = findViewById<Button>(R.id.logoutBtn)
LogoutBtn.setOnClickListener {
    firebaseAuth.signOut()
    val intent = Intent(this@User_Activity, MainActivity::class.java)
    intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
    startActivity(intent)
    finish()
}

完整修改后的代码

class User_Activity : AppCompatActivity() {

    private lateinit var binding: ActivityUserBinding
    private lateinit var databaseReference: DatabaseReference
    private lateinit var firebaseAuth: FirebaseAuth
    private lateinit var uid: String

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityUserBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 初始化FireAuth并校验登录状态
        firebaseAuth = FirebaseAuth.getInstance()
        val currentUser = firebaseAuth.currentUser
        if (currentUser == null) {
            startActivity(Intent(this, MainActivity::class.java))
            finish()
            return
        }
        uid = currentUser.uid
        databaseReference = FirebaseDatabase.getInstance().getReference("Users")

        // 加载用户数据
        loadUserDetails()

        // 登出按钮逻辑
        val LogoutBtn = findViewById<Button>(R.id.logoutBtn)
        LogoutBtn.setOnClickListener {
            firebaseAuth.signOut()
            val intent = Intent(this@User_Activity, MainActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
            startActivity(intent)
            finish()
        }

        // 导航栏跳转逻辑
        val addImg: ImageView = findViewById(R.id.navCreate)
        addImg.setOnClickListener {
            startActivity(Intent(this@User_Activity, Slam_Activity::class.java))
        }

        val gotoUser: ImageView = findViewById(R.id.navUser)
        gotoUser.setOnClickListener {
            Toast.makeText(this, "已在个人资料页", Toast.LENGTH_SHORT).show()
        }

        val gotoHome: ImageView = findViewById(R.id.navHome)
        gotoHome.setOnClickListener {
            startActivity(Intent(this@User_Activity, Homepage_Activity::class.java))
        }
    }

    private fun loadUserDetails() {
        val userRef = databaseReference.child(uid)

        userRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                val email = snapshot.child("email").value?.toString() ?: "未知邮箱"
                val username = snapshot.child("username").value?.toString() ?: "未知用户名"
                val userId = snapshot.child("id").value?.toString() ?: "未知ID"

                binding.profileUID.text = userId
                binding.profileEmail.text = email
                binding.profileUsername.text = username
            }

            override fun onCancelled(error: DatabaseError) {
                Log.e("FirebaseError", "数据读取失败: ${error.message}")
            }
        })
    }
}

内容的提问来源于stack exchange,提问作者John Villamor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:29