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

Firebase实时数据库ID存在判断误判问题求助

问题分析与解决

错误原因

你的检查逻辑存在核心问题:

  • 保存电影ID时,使用push()生成了随机子节点,数据结构大致如下:
    Users
      |--- [uid]
           |--- movie
                |--- -abc123: "电影ID1"
                |--- -def456: "电影ID2"
    
  • 而checkData()方法仅判断/Users/[uid]/movie父节点是否存在——只要用户保存过任意一部电影,这个父节点就会存在,snapshot.exists()就会返回true,完全没有检查当前电影ID是否在子节点中。

修正方案

方案1:遍历子节点检查电影ID

修改checkData()方法,遍历movie节点下的所有子节点,对比每个节点的值是否等于当前电影ID:

private fun checkData() {
    val movieId = args.movie?.id ?: return // 提前处理空值
    val postRef = firebaseDb.getReference("Users").child(uid).child("movie")

    postRef.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            var isExists = false
            // 遍历所有子节点,匹配当前电影ID
            for (childSnapshot in snapshot.children) {
                val savedId = childSnapshot.getValue(String::class.java)
                if (savedId == movieId) {
                    isExists = true
                    break
                }
            }
            if (isExists) {
                Log.e("Fragment", "${args.movie?.title} exists")
            } else {
                Log.e("Fragment", "${args.movie?.title} not exists")
            }
        }

        override fun onCancelled(error: DatabaseError) {
            Log.e("Fragment", error.toString())
        }
    })
}

方案2:优化数据结构(更高效)

把电影ID作为节点的键(而非值),可以直接通过键是否存在来检查,避免遍历,性能更优:

保存代码修改:

binding.ivStar.setOnClickListener {
    val movieId = args.movie?.id ?: return@setOnClickListener
    firebaseDb.getReference("Users").child(uid).child("movie").child(movieId)
        .setValue(true) // 值可以是任意标记,比如true、时间戳等
}

此时数据结构变为:

Users
    |--- [uid]
         |--- movie
              |--- "电影ID1": true
              |--- "电影ID2": true

检查代码修改:

private fun checkData() {
    val movieId = args.movie?.id ?: return
    val postRef = firebaseDb.getReference("Users").child(uid).child("movie").child(movieId)

    postRef.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            if (snapshot.exists()) {
                Log.e("Fragment", "${args.movie?.title} exists")
            } else {
                Log.e("Fragment", "${args.movie?.title} not exists")
            }
        }

        override fun onCancelled(error: DatabaseError) {
            Log.e("Fragment", error.toString())
        }
    })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:50:44