skip to Main Content

I have a RecyclerView list in which I display all the documents (each document has its own collection with data) from Firestore, and the question is how to display its corresponding data from Firestore in a new fragment when clicking on a list item

My Firestore collection
enter image description here
In the Recycler View, I display only the name and image for each item, but after clicking on the item, I want to open a new fragment where all the fields from the collection will be

ViewModel

class MainViewModel: ViewModel() {
    private val db = FirebaseFirestore.getInstance()
    private val auth = FirebaseAuth.getInstance()
    private val documentsLiveData = MutableLiveData<List<Card>>()

    fun getDocuments() {
        if (auth.currentUser != null){
            db.collection("cards")
                .get()
                .addOnSuccessListener { documents ->
                    val cardList = mutableListOf<Card>()
                    for (document in documents) {
                        val card = document.toObject(Card::class.java)
                        cardList.add(card)
                    }
                    documentsLiveData.value = cardList
                }
                .addOnFailureListener { exception ->
                    Log.e("Document error", exception.message.toString())
                }
        }
        else{
            Log.e("Document error", "Toast error")
        }

    }

    fun getDocumentsLiveData(): LiveData<List<Card>> {
        return documentsLiveData
    }
    

}

Adapter

class CardAdapter(private val context: Context,
                  private val list: List<Card>) : RecyclerView.Adapter<CardAdapter.MyViewHolder>() {

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

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val item = list[position]
        holder.itemView.card_name.text = item.name
        holder.itemView.card_description.text = item.description
        Glide.with(context)
            .load(item.img)
            .into(holder.itemView.card_img)
    }

    override fun getItemCount(): Int {
        return list.size

    }

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

    }
}

MainFragment

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewModel = ViewModelProvider(this)[MainViewModel::class.java]

        viewModel.getDocumentsLiveData().observe(viewLifecycleOwner) { cardList ->
            binding.progBar.visibility = View.GONE
            val adapter = CardAdapter(requireContext(), cardList)
            binding.mainRecycler.adapter = adapter
        }
        viewModel.getDocuments()
    }

I tried to do a search by element id, but it didn’t work out for me

2

Answers


  1. Best way:
    firstly show collections list
    secondly show files/collections list of select collection.

    Login or Signup to reply.
  2. To display the corresponding data from Firestore in a new fragment when clicking on a list item, you can follow these steps:

    In your CardAdapter, add a click listener to the item view in the onBindViewHolder method:

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val item = list[position]
        holder.itemView.card_name.text = item.name
        holder.itemView.card_description.text = item.description
        Glide.with(context)
            .load(item.img)
            .into(holder.itemView.card_img)
    
        holder.itemView.setOnClickListener {
            val action = MainFragmentDirections.actionMainFragmentToDetailFragment(item.id)
            it.findNavController().navigate(action)
        }
    }
    

    In your MainFragment, create a new NavDirections object that includes the document ID as an argument:

    val action = MainFragmentDirections.actionMainFragmentToDetailFragment(item.id)
    

    Create a new DetailFragment that will display the corresponding data from Firestore. In the onCreateView method of the DetailFragment, retrieve the document ID from the arguments and use it to query Firestore for the corresponding document:

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val args = DetailFragmentArgs.fromBundle(requireArguments())
        val db = FirebaseFirestore.getInstance()
        val docRef = db.collection("cards").document(args.documentId)
    
        docRef.get().addOnSuccessListener { document ->
            if (document != null) {
                val card = document.toObject(Card::class.java)
                // Display the data in the UI
            } else {
                Log.d(TAG, "No such document")
            }
        }.addOnFailureListener { exception ->
            Log.d(TAG, "get failed with ", exception)
        }
    
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_detail, container, false)
    }
    

    In the DetailFragment, display the corresponding data from Firestore in the UI. You can use the card object that you retrieved from Firestore in step 3 to populate the UI elements.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search