Aksa Benny
Aksa Benny

Reputation: 1

I can't retrieve the data from the realtime database to the recycler view

I am new to Kotlin and to programming too.

RestaurantModel.kt

package com.example.foodtogo.model

import android.os.Parcel
import android.os.Parcelable
import java.io.Serializable


class RestaurantModel(val name:String?, val address:String?, val delivery_charge: Int, val image: String?, val open: String?,
                      var menus: List<Menus?>?): Serializable {}

 class Menus(val name:String?, val price: Float, val url:String?, var totalInCart: Int):Serializable {}

RestaurantMainActivity.kt

package com.example.foodtogo

import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.foodtogo.databinding.ActivityRestaurantMainBinding
import com.example.foodtogo.model.RestaurantModel
import com.example.foodtogo.view.RestaurantListAdapter
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import android.content.Intent as Intent



class RestaurantMainActivity : AppCompatActivity(){
    private lateinit var binding: ActivityRestaurantMainBinding
    private lateinit var firebaseAuth: FirebaseAuth
    private lateinit var database: FirebaseDatabase
    private lateinit var reference: DatabaseReference
    private lateinit var restaurantList: ArrayList<RestaurantModel>
    //var adapter: RestaurantListAdapter?=null
    //private lateinit var restaurantList: MutableList<RestaurantModel?>
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityRestaurantMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        firebaseAuth = FirebaseAuth.getInstance()
        database = FirebaseDatabase.getInstance()
        reference = database.reference
        Log.e("AKSA", "TEST1")
        binding.recyclerViewRestaurant.layoutManager = LinearLayoutManager(this)
        Log.e("AKSA", "TEST")
        restaurantList = arrayListOf<RestaurantModel>()
        getRestaurantData()
        Log.e("AKSA", "TEST3")
    }
    private fun getRestaurantData() {
        
        reference=FirebaseDatabase.getInstance().getReference("RestaurantModel")
        reference.addValueEventListener(object : ValueEventListener,RestaurantListAdapter.ValueEventListener{
            override fun onDataChange(snapshot: DataSnapshot) {
                Log.e("AKSA", "TEST6")
                Log.e("AKSA", "TEST $snapshot")
                if (snapshot.exists()) {
                    Log.e("AKSA", "TEST00")
                    for (userSnapshot in snapshot.children) {
                        Log.e("AKSA", "TEST01")
                        val user =
                            userSnapshot.child("RestaurantModel").getValue(RestaurantModel::class.java)
                        Log.e("AKSA", "TEST02")
                        if (user != null) {
                            Log.e("AKSA", "TEST03")
                            restaurantList.add(user)
                        }
                    }
                    val adapter = RestaurantListAdapter(restaurantList, this)
                    binding.recyclerViewRestaurant.adapter = adapter
                    adapter.notifyDataSetChanged()
                }
            }

            override fun onCancelled(error: DatabaseError) {
                Toast.makeText(applicationContext, error.getMessage(), Toast.LENGTH_LONG).show()
            }

            override fun onItemClick(restaurantModel: RestaurantModel) {
                val intent = Intent(applicationContext,RestaurantMenuActivity::class.java)
                intent.putExtra("RestaurantModel", restaurantModel)
                    startActivity(intent)
                    Log.d("AKSA", "MESSAGE")
            }
        })
    }
        override fun onCreateOptionsMenu(menu: Menu?): Boolean {
            menuInflater.inflate(R.menu.menubar, menu)
            return super.onCreateOptionsMenu(menu)
        }
        override fun onOptionsItemSelected(item: MenuItem): Boolean {
            when (item.itemId) {
                R.id.home_menu -> {
                    val intent = Intent(this, ViewOrderActivity::class.java)
                    startActivity(intent)
                }
                R.id.signout_menu -> {
                    firebaseAuth.signOut()
                    val intent = Intent(this, LOGIN::class.java)
                    intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
                    startActivity(intent)
                    finish()
                }
            }
            return super.onOptionsItemSelected(item)
        }
    }

RestaurantListAdapter.kt

package com.example.foodtogo.view

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.foodtogo.R
import com.example.foodtogo.model.RestaurantModel
import com.google.firebase.database.ValueEventListener

class RestaurantListAdapter(val restaurantList: ArrayList<RestaurantModel>, val clickListener: ValueEventListener):
    RecyclerView.Adapter<RestaurantListAdapter.MyViewHolder>() {
    //private lateinit var database: FirebaseDatabase
    //private lateinit var reference:DatabaseReference

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RestaurantListAdapter.MyViewHolder {
        val view: View = LayoutInflater.from(parent.context).inflate(R.layout.recycler_restaurantlist,parent,false)
        return MyViewHolder(view)



    }
    override fun onBindViewHolder(holder: RestaurantListAdapter.MyViewHolder, position: Int) {
        holder.bind(restaurantList.get(position))
        holder.itemView.setOnClickListener{
            clickListener.onItemClick(restaurantList.get(position))
        }
    }
    override fun getItemCount(): Int {
        return restaurantList.size
    }
    inner class MyViewHolder(view: View):RecyclerView.ViewHolder(view){

        val thumbImage: ImageView =view.findViewById(R.id.thumbImage)
        val restaurantName: TextView =view.findViewById(R.id.restaurantName)
        val restaurantAddress:TextView=view.findViewById(R.id.restaurantAddress)
        val restaurantHours:TextView=view.findViewById(R.id.restaurantHours)
        fun bind(restaurantModel: RestaurantModel?){
            restaurantName.text=restaurantModel?.name
            restaurantAddress.text="Address: "+restaurantModel?.address
            restaurantHours.text="Open: "+restaurantModel?.open
            Glide.with(this.thumbImage).load(restaurantModel?.image).centerCrop().placeholder(R.drawable.ic_launcher_background).into(thumbImage)

        }
    }
    interface ValueEventListener {
        fun onItemClick(restaurantModel: RestaurantModel)
    }
}

"Log.e("AKSA", "TEST02")". Till this prints. But after this, user shows null value. First I used parcelize in the RestaurantModel.kt, later I changed and add serializable. I checked other programs too. But I am stuck. I don't understand where it goes wrong.

enter image description here

Upvotes: 0

Views: 115

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 138824

To solve the issue please use the following lines of code:

val db = Firebase.database.reference
val restaurantModelRef = db.child("RestaurantModel")
restaurantModelRef.get().addOnCompleteListener {
    if (it.isSuccessful) {
        val snapshot = it.result
        for (restaurant in snapshot.children) {
            val restaurantModel = restaurant.getValue(RestaurantModel::class.java)
            restaurantList.add(restaurantModel)
        }
        val adapter = RestaurantListAdapter(restaurantList, getApplicationContext())
        binding.recyclerViewRestaurant.adapter = adapter
        adapter.notifyDataSetChanged()
    }
}

Things to notice:

  1. I have used get() instead of addValueEventListener().
  2. There is no need to call child() on the DataSnapshot object inside the callback.
  3. It will be more convenient to create an adapter with an empty list, and inside the callback just to notify about the changes.

Upvotes: 0

Related Questions