I'm trying to populate a recycler view with data fetched from Firestore, following a few tutorials and this documentation: https://github.com/firebase/FirebaseUI-Android/tree/master/firestore#using-the-firestorerecycleradapter. It seems, that the number fetched from the database (currently 3) is correct, but there is no data displayed. In addition I already have log messages throughout the code to monitor the values, but the actual values remain empty.
private var adapter: FirestoreCommanderNamesRecyclerAdapter? = null
Then start listening to the the adapter:
override fun onStart() {
super.onStart()
adapter!!.startListening()
Log.d(TAG, "onStart -> start listening to the adapter")
}
Then in the onViewCreated
I call a function, that should populate the recyclerview:
private fun invokeRecyclerView(){
val rootRef = FirebaseFirestore.getInstance()
val query = rootRef!!.collection("commanders")
//TODO: Here is something off
val options = FirestoreRecyclerOptions.Builder<FirestoreCommanderNames>().setQuery(query, FirestoreCommanderNames::class.java).build()
adapter = FirestoreCommanderNamesRecyclerAdapter(options)
binding.fragmentCommanderSettingsRecyclerview.layoutManager = LinearLayoutManager(this.context)
binding.fragmentCommanderSettingsRecyclerview.adapter = adapter
}
Here is the class FirestoreCommanderNamesRecyclerAdapter
:
class FirestoreCommanderNamesRecyclerAdapter constructor(options: FirestoreRecyclerOptions<FirestoreCommanderNames>):
FirestoreRecyclerAdapter<FirestoreCommanderNames, FirestoreCommanderNamesViewHolder>(options){
private val TAG = "CmdrNamesRecyclerAdapte"
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): FirestoreCommanderNamesViewHolder {
Log.d(TAG, "onCreateViewHolder started")
val view = LayoutInflater.from(parent.context).inflate(R.layout.settings_name_list_item, parent, false)
return FirestoreCommanderNamesViewHolder(view)
}
override fun onBindViewHolder(
holder: FirestoreCommanderNamesViewHolder,
position: Int,
model: FirestoreCommanderNames
) {
Log.d(TAG, "onBindViewHolder started")
Log.d(TAG, "onBindViewHolder Model Commander Name: ${model.commander_names_ID}, position: $position")
holder.setCommanderName(model.commander_names_ID )
}
override fun onError(e: FirebaseFirestoreException) {
super.onError(e)
Log.d(TAG, "Error: $e")
}
}
And the FirestoreCommanderNamesViewHolder
:
class FirestoreCommanderNamesViewHolder constructor(private val view: View) : RecyclerView.ViewHolder(view){
private val TAG = "CmdrNamesViewHolder"
internal fun setCommanderName(commanderNames: String){
Log.d(TAG, "Viewholder Value: $commanderNames")
val textView = view.findViewById<TextView>(R.id.settings_list_item_textview_name)
textView.text = commanderNames
}
}
the data class FirestoreCommanderNames
used:
data class FirestoreCommanderNames(
val commander_names_ID: String = "",
val commander_names_NAME: String = ""
)
This is, how the data is structured:
And my dependencies used:
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:32.0.0')
// When using the BoM, don't specify versions in Firebase dependencies
implementation 'com.google.firebase:firebase-analytics-ktx'
implementation("com.google.firebase:firebase-crashlytics-ktx")
implementation("com.google.firebase:firebase-auth-ktx")
implementation("com.google.firebase:firebase-firestore-ktx")
implementation 'com.google.firebase:firebase-core:21.1.1'
implementation("com.google.firebase:firebase-perf-ktx")
implementation("com.google.firebase:firebase-config-ktx")
implementation("com.google.firebase:firebase-messaging-ktx")
implementation 'com.google.firebase:firebase-database-ktx'
implementation 'com.google.firebase:firebase-storage-ktx'
// Firebase UI
implementation 'com.firebaseui:firebase-ui-auth:8.0.2'
implementation 'com.firebaseui:firebase-ui-database:8.0.2'
implementation 'com.firebaseui:firebase-ui-firestore:8.0.2'
implementation 'com.firebaseui:firebase-ui-storage:8.0.2'
implementation "androidx.legacy:legacy-support-v4:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.3.0"
</pre>
Putting a dummy text value in the setup (rather than the query), Query itself, Resource references
As Doug commented, the structure of your FirestoreCommanderNames
doesn't match the data in the document you show, so the Firestore SDK has no way to automatically map the values for you.
The most direct mapping is:
data class FirestoreCommanderNames(
val Name: String = ""
)
Note how the Name
here matches the exact field name in the database? That's how Firebase knows how to map between the database and your class.
If you want to also map the document ID from the metadata to your class, you can use a @DocumentId
annotation to do so:
data class FirestoreCommanderNames(
@DocumentId val ID: String = "",
val Name: String = ""
)