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

- Firebase控制台数据结构:

核心代码
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) {} }) } }
问题排查与修复方案
查询逻辑错误
当前查询是对节点键名做前缀匹配,而非comment字段。修改查询代码,指定搜索字段:val quer: Query = firebaseDatabase.getReference("Comments") .orderByChild("comment") .startAt(query) .endAt("$query\uf8ff") // 修正转义符为\uf8ff数据类型转换风险
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大小写敏感问题
Firebase查询默认大小写敏感,若需不区分大小写,需在数据库中存储comment的小写副本(如commentLower),查询时用小写关键词:val lowerQuery = query.lowercase() val quer: Query = firebaseDatabase.getReference("Comments") .orderByChild("commentLower") .startAt(lowerQuery) .endAt("$lowerQuery\uf8ff")导航栏语法错误
修复bottomnav.setOnNavigationItemSelectedListener中的箭头符号:item -改为item ->,避免编译错误。调试建议
- 在
onDataChange中添加日志,确认是否获取到数据:Log.d("SearchDebug", "数据数量:${snapshot.childrenCount}") - 检查Firebase规则,确保
Comments节点允许读取:{ "rules": { "Comments": { ".read": true, ".write": "auth != null" } } }
- 在
内容的提问来源于stack exchange,提问作者LORD SHIVA PRODUCT
相关产品推荐
相关产品推荐

