I am trying to show my firebase realtime database items in recycleview Kotlin

Viewed 57

I can't seem to figure out what to do to get my RecycleView to show the data as of now it makes the number of views I want but it doesn't show the data assigned to each it just shows white space.

My ListPage class:

class ListsPage : AppCompatActivity() {
private lateinit var dbRef : DatabaseReference
private lateinit var itemRecyclerView: RecyclerView
private lateinit var itemArrayList: ArrayList<ItemData>


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_lists_page)
    dbRef = Firebase.database.reference
    itemRecyclerView =  findViewById(R.id.itemList)
    itemRecyclerView.layoutManager = LinearLayoutManager(this)
    itemRecyclerView.setHasFixedSize(true)

    itemArrayList = arrayListOf<ItemData>()

    getItemData()


}

private fun getItemData() {
    dbRef =  FirebaseDatabase.getInstance().getReference("Items")

    dbRef.addValueEventListener(object : ValueEventListener{
        override fun onDataChange(snapshot: DataSnapshot) {



            if (snapshot.exists()){
                for(itemSnapshot in snapshot.children ){

                    val item = itemSnapshot.getValue(ItemData::class.java)
                    itemArrayList.add(item!!) 

                }
                // attaching adapter to recycler view
                itemRecyclerView.adapter = MyAdapter(itemArrayList)
            }
        }

        override fun onCancelled(error: DatabaseError) {

            Log.w(TAG, "loadPost:onCancelled", error.toException())

        }

    })

  }

MY ADAPTER CLASS

class MyAdapter(private val itemList : ArrayList<ItemData>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>(){




    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.lists_page_recy_view,
        parent, false)

        return MyViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val currentItem  = itemList[position]

        holder.itemNameAD.text = currentItem.name
        holder.brandNameAD.text = currentItem.brand
        holder.typeItemAD.text = currentItem.type
        holder.priceItemAD.text = currentItem.price
        holder.amountAD.text = currentItem.amount
    }

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

    class MyViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) {

        val itemNameAD : TextView = itemView.findViewById(R.id.itemName)
        val brandNameAD : TextView = itemView.findViewById(R.id.itemBrand)
        var typeItemAD : TextView = itemView.findViewById(R.id.itemType)
        val priceItemAD : TextView = itemView.findViewById(R.id.itemPrice)
        val amountAD : TextView = itemView.findViewById(R.id.itemAmount)


    }

}

ITEM DATA CLASS

data class ItemData(var name : String? = null,var brand : String? =null, var type : String? = null, var price : String? =null, var amount : String? = null)

GRADLE

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'com.google.gms.google-services'
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.pp4_project"
        minSdk 19
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.6.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.annotation:annotation:1.4.0'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'

    implementation 'com.google.firebase:firebase-database-ktx:20.0.6'

    implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
    implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    implementation 'com.firebaseui:firebase-ui-database:6.2.1'
    implementation platform('com.google.firebase:firebase-bom:30.2.0')
    implementation 'com.google.firebase:firebase-analytics-ktx'
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:30.4.1')
    // Add the dependency for the Firebase Authentication library
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation 'com.google.firebase:firebase-auth-ktx'
    // Also add the dependency for the Google Play services library and specify its version
    implementation 'com.google.android.gms:play-services-auth:20.3.0'
      

Database Json file structure

"Items": {
    "BRZ": {
      "amountData": "3",
      "brandData": "Subaru",
      "nameData": "BRZ",
      "priceData": "25000",
      "typeData": "Sports Car"
    },
    "Betty": {
      "amountData": "1",
      "brandData": "gucci",
      "nameData": "Betty",
      "priceData": "999999",
      "typeData": "Human"
    },
    "Haraches": {
      "amountData": "30",
      "brandData": "Nike",
      "nameData": "Haraches",
      "priceData": "125",
      "typeData": "Shoe"
    },
    "Patricia ": {
      "amountData": "1",
      "brandData": "gucci",
      "nameData": "Patricia ",
      "priceData": "999999",
      "typeData": "woman"
    },
    "TV": {
      "amountData": "100",
      "brandData": "Samsung ",
      "nameData": "TV",
      "priceData": "500",
      "typeData": "Electronic "
    },
    "bud": {
      "amountData": "1000",
      "brandData": "cali",
      "nameData": "bud",
      "priceData": "10",
      "typeData": "smoke"
    },
    "caca": {
      "amountData": "2",
      "brandData": "caca",
      "nameData": "caca",
      "priceData": "20",
      "typeData": "caca"
    },
    "ggg": {
      "amountData": "6",
      "brandData": "hhh",
      "nameData": "ggg",
      "priceData": "96",
      "typeData": "bb"
    }
  }
}

I want to know what I am doing wrong and have some tips to better my code also why my data is not transferring into the recycle view but it saving in my variables and getting the data from the server but then turning it to null why is this happening.

1 Answers

The problem lies in the fact that the names in your ItemData class are different than the names that exist in the database. For example, in the database, you have a field called amountData while in your ItemData class is called amount, and this is not correct. The fields must match.

To solve this, you have two solutions. The first one would be to change the name of the fields inside the class to match the one in the database:

data class ItemData(
    var nameData: String? = null,
    var brandData: String? =null,
    var typeData: String? = null,
    var priceData: String? = null,
    var amountData: String? = null
)

Or you can leave the class as it is and add the following annotations before each field:

data class ItemData(
    @get:PropertyName("nameData")
    @set:PropertyName("nameData")
    @PropertyName("nameData")
    var name: String? = null,
    @get:PropertyName("brandData")
    @set:PropertyName("brandData")
    @PropertyName("brandData")
    var brand: String? =null,
    @get:PropertyName("typeData")
    @set:PropertyName("typeData")
    @PropertyName("typeData")
    var type: String? = null,
    @get:PropertyName("priceData")
    @set:PropertyName("priceData")
    @PropertyName("priceData")
    var price: String? = null,
    @get:PropertyName("amountData")
    @set:PropertyName("amountData")
    @PropertyName("amountData")
    var amount: String? = null
)
Related