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

使用Firebase Database与Kotlin搜索时布局无法加载求助

Firebase Realtime Database搜索功能无结果加载问题

我正在开发一个功能:允许用户在Firebase Realtime Database中搜索文本,若内容存在则加载对应RecyclerView布局。当前使用Kotlin开发,但即使搜索词存在于Firebase的Comments子节点中,布局也无法加载(无搜索结果展示)。

相关截图

  • 搜索界面无结果展示:Search activity layout not inflated
  • Firebase控制台数据结构:Firebase console data

核心代码

Search Activity代码

class Search : AppCompatActivity() {
    private lateinit var bottomnav : BottomNavigationView
    private lateinit var commentRecyclerView: RecyclerView
    private lateinit var commentAdapter: Searchcommmentadapter
    private lateinit var firebaseDatabase: FirebaseDatabase
    private lateinit var databaseReference: DatabaseReference
    private lateinit var adapter:Searchcommmentadapter
    private lateinit var commentList: List<Comment>
    private lateinit var searchview : SearchView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_search)
        bottomnav = findViewById(R.id.bottomnavigation)
        commentRecyclerView = findViewById(R.id.rv)
        searchview = findViewById(R.id.searchui)

        searchview.setOnQueryTextListener(object: SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                query?.let { fetch(it) }
                return false
            }

            override fun onQueryTextChange(query: String?): Boolean {
                query?.let { fetch(it) }
                return false
            }
        })

        commentRecyclerView.setHasFixedSize(false)
        commentRecyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
        commentRecyclerView.layoutManager = LinearLayoutManager(this)

        bottomnav.selectedItemId = R.id.csearch
        bottomnav.setOnNavigationItemSelectedListener { item ->
            when(item.itemId){
                R.id.home ->{
                    startActivity(Intent(this, MainActivity::class.java))
                    overridePendingTransition(0,0)
                    true
                }
                R.id.cv ->{
                    startActivity(Intent(this, activity_for_playing_soma_videos::class.java))
                    overridePendingTransition(0,0)
                    true
                }
                R.id.ch ->{
                    startActivity(Intent(this, ForSomasunthaVideoActivity_CH::class.java))
                    overridePendingTransition(0,0)
                    true
                }
                R.id.ctrend ->{
                    startActivity(Intent(this, TrendingPosts::class.java))
                    overridePendingTransition(0,0)
                    true
                }
                R.id.csearch->{
                    overridePendingTransition(0,0)
                    true
                }
                else -> false
            }
        }
    }

    private fun fetch(query : String){
        firebaseDatabase = FirebaseDatabase.getInstance()
        val event = object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                commentList = ArrayList()
                for(postsnap in snapshot.children) {
                    val comment: Comment? = postsnap.getValue(Comment::class.java)
                    comment?.let {
                        (commentList as ArrayList<Comment>).add(it)
                    }
                }
                commentAdapter = Searchcommmentadapter(this@Search, commentList.asReversed())
                commentRecyclerView.adapter = commentAdapter
            }

            override fun onCancelled(error: DatabaseError) {}
        }
        val quer: Query = firebaseDatabase.getReference("Comments").startAt(query).endAt("$query/uf8ff")
        quer.addListenerForSingleValueEvent(event)
    }
}

Search RecyclerView Adapter代码

class Searchcommmentadapter(private var context:Context, private var data: List<Comment>): RecyclerView.Adapter<Searchcommmentadapter.MyViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Searchcommmentadapter.MyViewHolder {
        val row: View = LayoutInflater.from(context).inflate(R.layout.searchui, parent, false)
        return MyViewHolder(row)
    }

    override fun onBindViewHolder(holder: Searchcommmentadapter.MyViewHolder, position: Int) {
        holder.lang.text = data[position].getPostLangBl()
        holder.commentTv.text = data[position].getComment()
        glidesh(position, holder.profile, holder.card)
        holder.shivprofile.text = data[position].getUserName()
        isLiked(data[position].getCommentKey().toString(), holder.willlike)
        nrLikes(holder.likecount, data[position].getCommentKey().toString())
    }

    private fun glidesh(position: Int, profile: ImageView, card: CardView) {
        Glide.with(context).load(data[position].getUri()).into(profile)
        if(data[position].getuEmail().toString() == "namashivayacompany@gmail.com"){
            card.setCardBackgroundColor(ContextCompat.getColor(context, R.color.red))
        } else {
            card.setCardBackgroundColor(ContextCompat.getColor(context, R.color.yellow))
        }
    }

    override fun getItemCount(): Int {
        return data.size
    }

    inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var commentTv: TextView = itemView.findViewById(R.id.comment_text)
        var sharepost: ImageView = itemView.findViewById(R.id.post_share_somam)
        var profile:ImageView = itemView.findViewById(R.id.profile1)
        var shivprofile: TextView = itemView.findViewById(R.id.namesh)
        var card: CardView = itemView.findViewById(R.id.lpshiv)
        var willlike: ImageView = itemView.findViewById(R.id.ratingBar)
        var likecount: TextView =itemView.findViewById(R.id.likecount)
        var lang: TextView =itemView.findViewById(R.id.lang)

        init{
            itemView.setOnClickListener {
                val intent = Intent(context, viewing_post_nama::class.java)
                val position: Int = adapterPosition
                intent.putExtra("Comment", data[position].getComment())
                intent.putExtra("UserName", data[position].getUserName())
                intent.putExtra("Uri", data[position].getUri())
                intent.putExtra("Postlang", data[position].getPostLangBl())
                context.startActivity(intent)
            }

            sharepost.setOnClickListener{
                val shareIntent = Intent(Intent.ACTION_SEND)
                val text = data[adapterPosition].getComment() + "\n" + "  " + "Download Commenting App Now ! ! ! :) "
                shareIntent.type = "text/plain"
                shareIntent.putExtra(Intent.EXTRA_TEXT, text)
                context.startActivity(Intent.createChooser(shareIntent,"SHARE COMMENT"))
            }

            profile.setOnClickListener{
                Snackbar.make(itemView.findViewById(R.id.shivaa), "WELCOME ! ! !", Snackbar.LENGTH_INDEFINITE).show()
            }

            val firebaseuser : FirebaseUser? = FirebaseAuth.getInstance().currentUser
            willlike.setOnClickListener{
                if(willlike.tag.equals("like")){
                    firebaseuser?.let {
                        FirebaseDatabase.getInstance().getReference().child("LikesOnly")
                            .child(data[adapterPosition].getCommentKey().toString())
                            .child(it.uid).setValue(true)
                    }
                } else {
                    firebaseuser?.let {
                        FirebaseDatabase.getInstance().getReference().child("LikesOnly")
                            .child(data[adapterPosition].getCommentKey().toString())
                            .child(it.uid).removeValue()
                    }
                }
            }
        }
    }

    private fun isLiked(postId:String, imageview: ImageView ){
        val firebaseuser : FirebaseUser? = FirebaseAuth.getInstance().currentUser
        val myRef: DatabaseReference = FirebaseDatabase.getInstance().getReference("LikesOnly").child(postId)

        myRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                firebaseuser?.let {
                    if(snapshot.child(it.uid).exists()){
                        imageview.setImageResource(R.drawable.liked)
                        imageview.setTag("liked")
                    } else {
                        imageview.setImageResource(R.drawable.disliked)
                        imageview.setTag("like")
                    }
                }
            }

            override fun onCancelled(error: DatabaseError) {}
        })
    }

    private fun nrLikes(likes : TextView,  postId : String){
        val myRef: DatabaseReference = FirebaseDatabase.getInstance().getReference("LikesOnly").child(postId)

        myRef.addValueEventListener(object : ValueEventListener {
            @SuppressLint("SetTextI18n")
            override fun onDataChange(snapshot: DataSnapshot) {
                likes.text = snapshot.childrenCount.toString() + " " + "Likes"
            }

            override fun onCancelled(error: DatabaseError) {}
        })
    }
}

问题排查与修复方案

  1. 查询逻辑错误
    当前查询是对节点键名做前缀匹配,而非comment字段。修改查询代码,指定搜索字段:

    val quer: Query = firebaseDatabase.getReference("Comments")
        .orderByChild("comment")
        .startAt(query)
        .endAt("$query\uf8ff") // 修正转义符为\uf8ff
    
  2. 数据类型转换风险
    commentList声明为List<Comment>,强制转ArrayList可能异常,改为直接初始化:

    override fun onDataChange(snapshot: DataSnapshot) {
        val tempList = ArrayList<Comment>()
        for(postsnap in snapshot.children) {
            val comment = postsnap.getValue(Comment::class.java)
            comment?.let { tempList.add(it) }
        }
        commentList = tempList.asReversed()
        commentAdapter.notifyDataSetChanged()
    }
    

    同时在onCreate中提前初始化Adapter:

    commentList = emptyList()
    commentAdapter = Searchcommmentadapter(this, commentList)
    commentRecyclerView.adapter = commentAdapter
    
  3. 大小写敏感问题
    Firebase查询默认大小写敏感,若需不区分大小写,需在数据库中存储comment的小写副本(如commentLower),查询时用小写关键词:

    val lowerQuery = query.lowercase()
    val quer: Query = firebaseDatabase.getReference("Comments")
        .orderByChild("commentLower")
        .startAt(lowerQuery)
        .endAt("$lowerQuery\uf8ff")
    
  4. 导航栏语法错误
    修复bottomnav.setOnNavigationItemSelectedListener中的箭头符号:item -改为item ->,避免编译错误。

  5. 调试建议

    • 在onDataChange中添加日志,确认是否获取到数据:Log.d("SearchDebug", "数据数量:${snapshot.childrenCount}")
    • 检查Firebase规则,确保Comments节点允许读取:
      {
        "rules": {
          "Comments": {
            ".read": true,
            ".write": "auth != null"
          }
        }
      }
      

内容的提问来源于stack exchange,提问作者LORD SHIVA PRODUCT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:45:01