Filtering ArrayList Determining a Firebase RealTime-Database Reference Child
I'm trying to filter three RecyclerViews
on an activity based on a property that children have in one of my RTDB references have. On my ServiceActivity
, I have the three RecyclerViews
and I need help in knowing what I need to do to perform the filters. Do I need to create an empty ArrayList
for each category
property name and then perform the filter function on each? Or how would I perform this? Thank you!
What I Have
A RTDB Reference Child
ServiceActivity.kt
lateinit var autoJobServicesAdapter: JobServicesAdapter
lateinit var homeJobServicesAdapter: JobServicesAdapter
lateinit var personalJobServicesAdapter: JobServicesAdapter
val jobServices = ArrayList<JobService>()
val jobServicesDatabaseRef = FirebaseDatabase.getInstance().reference.child(REF_JOB_SERVICES)
val autoServices = ArrayList<JobService>()
val homeServices = ArrayList<JobService>()
val personalServices = ArrayList<JobService>()
private fun setupAutoRecyclerView() {
autoJobServicesAdapter = JobServicesAdapter(jobServices)
val autoRecyclerView = findViewById<RecyclerView>(R.id.autoServicesRecyclerView)
autoRecyclerView.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
adapter = autoJobServicesAdapter
setHasFixedSize(true)
}
jobServicesDatabaseRef.orderByChild("jobName").addValueEventListener(object: ValueEventListener {
@SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
jobServices.clear()
for (snap in snapshot.children) {
val jobService = JobService(snap.child("category").getValue(String::class.java)!! ,
snap.child("jobName").getValue(String::class.java)!! , snap.child("jobImageUrl").getValue(String::class.java)!! ,
snap.child("jobServiceImageUrl").getValue(String::class.java)!!)
jobServices.add(jobService)
}
autoJobServicesAdapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
Log.d("ServiceActivity", "LoadPost:onCancelled", error.toException())
}
})
}
private fun setupHomeRecyclerView() {
homeJobServicesAdapter = JobServicesAdapter(jobServices)
val homeRecyclerView = findViewById<RecyclerView>(R.id.homeServicesRecyclerView)
homeRecyclerView.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
adapter = homeJobServicesAdapter
setHasFixedSize(true)
}
jobServicesDatabaseRef.orderByChild("jobName").addValueEventListener(object: ValueEventListener {
@SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
jobServices.clear()
for (snap in snapshot.children) {
val jobService = JobService(snap.child("category").getValue(String::class.java)!! ,
snap.child("jobName").getValue(String::class.java)!! , snap.child("jobImageUrl").getValue(String::class.java)!! ,
snap.child("jobServiceImageUrl").getValue(String::class.java)!!)
jobServices.add(jobService)
}
homeJobServicesAdapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
Log.d("ServiceActivity", "LoadPost:onCancelled", error.toException())
}
})
}
private fun setupPersonalRecyclerView() {
personalJobServicesAdapter = JobServicesAdapter(jobServices)
val personalRecyclerView = findViewById<RecyclerView>(R.id.personalServicesRecyclerView)
personalRecyclerView.apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
adapter = personalJobServicesAdapter
setHasFixedSize(true)
}
jobServicesDatabaseRef.orderByChild("jobName").addValueEventListener(object: ValueEventListener {
@SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
jobServices.clear()
for (snap in snapshot.children) {
val jobService = JobService(snap.child("category").getValue(String::class.java)!! ,
snap.child("jobName").getValue(String::class.java)!! , snap.child("jobImageUrl").getValue(String::class.java)!! ,
snap.child("jobServiceImageUrl").getValue(String::class.java)!!)
jobServices.add(jobService)
}
personalJobServicesAdapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
Log.d("ServiceActivity", "LoadPost:onCancelled", error.toException())
}
})
}
Solution 1:
You're loading the exact same data from Firebase three times. While the client is smart enough to deduplicate these queries for you, it's still better to only process the same data once.
How about creating the three views, list, and adapters all at once, and then loading the data for each with this single snippet? Something like this:
private fun loadDataForRecyclerViews() {
jobServicesDatabaseRef.orderByChild("jobName").addValueEventListener(object: ValueEventListener {
@SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
jobServices.clear()
for (snap in snapshot.children) {
// 👇 Load the category and the job
val category = category
val jobService = (category ,
snap.child("jobName").getValue(String::class.java)!! , snap.child("jobImageUrl").getValue(String::class.java)!! ,
snap.child("jobServiceImageUrl").getValue(String::class.java)!!)
// 👇 Put the job in the correct list based on its category
if (category == "auto") {
autoJobServices.add(jobService)
}
else if (category == "home") {
homeJobServices.add(jobService)
}
else if (category == "personal") {
personalJobServices.add(jobService)
}
}
// 👇 Refresh all views
autoJobServicesAdapter.notifyDataSetChanged()
homeJobServicesAdapter.notifyDataSetChanged()
personalJobServicesAdapter.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {
Log.d("ServiceActivity", "LoadJobs", error.toException())
}
})
}
Note: I did not compile this code, but merely provide it as a starting point. If you get a compiler error, please try to fix it on your own before commenting about it.