0

My RecyclerView is working when I use dummy data, but displays an empty result for RecyclerView when connected to Firebase database. Please help to solve this issue.

override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        var adapter = qponAdapter(generateData())
        val layoutManager = LinearLayoutManager(context)
        qponRecyclerView?.layoutManager = layoutManager
        qponRecyclerView?.itemAnimator = DefaultItemAnimator()

        qponRecyclerView?.adapter = adapter
        adapter.notifyDataSetChanged()
}

private fun generateData(): ArrayList<Company> {

    var companyReg = Company(name = "qqqqq", br = "", country = "", city = "", address = "", tel = "", value = "", qponQuantity = 0, email = "", advApproved = "false", advPassword = "", startDate = "", endDate = "", conditions = "", postApproved = "false", order = 10000, authPhone = "",nodeID = "")
    companyList.add(companyReg)
    companyList.add(companyReg)
    companyList.add(companyReg)
    companyList.add(companyReg)
    companyList.add(companyReg)
}

It is working well and display 5 record in Recyclerview.

private fun generateData(): ArrayList<Company> {
            val postListener = object : ValueEventListener {
                override fun onDataChange(dataSnapshot: DataSnapshot) {
                    // Get Post object and use the values to update the UI
                    //val post = dataSnapshot.getValue<Post>(Post::class.java!!)
                    // ...
                    val td = dataSnapshot.value as HashMap<*, *>



                    for (key in td.keys){
                        val post = td[key] as HashMap<*, *>

                        val companyReg = Company(name = "", br = "", country = "", city = "", address = "", tel = "", value = "", qponQuantity = 0, email = "", advApproved = "false", advPassword = "", startDate = "", endDate = "", conditions = "", postApproved = "false", order = 10000, authPhone = "",nodeID = "")

                        companyReg.name = post["Name"].toString()
                        companyReg.address = post["Address"].toString()
                        companyReg.country = post["Country"].toString()
                        companyReg.city = post["City"].toString()
                        companyReg.tel = post["Tel"].toString()
                        companyReg.value = post["qponValue"].toString()
                        //companyReg.qponQuantity = qponQuantity
                        companyReg.email = post["Email"].toString()
                        companyReg.advPassword = post["advPassword"].toString()

                        companyReg.startDate = post["startDate"].toString()
                        companyReg.endDate = post["endDate"].toString()
                        companyReg.conditions = post["Conditions"].toString()

                        companyReg.postApproved = post["PostApproved"].toString()
                        companyReg.advApproved = post["advApproved"].toString()
                        //companyReg.order = post["Order"] as! Int
                        companyReg.authPhone = post["authPhone"].toString()
                        companyReg.nodeID = key.toString()

                        println(companyReg.nodeID)
                        println(companyReg.address)


                        companyList.add(companyReg)
                    }


                }

                override fun onCancelled(databaseError: DatabaseError) {
                    // Getting Post failed, log a message
                    Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
                    // ...
                }
            }
            myRef.addValueEventListener(postListener)


        return companyList
    }

It connected to Firebase database but the RecyclerView display 0 record. I am sure it is connecting to the database because it print out every record in the console.

CEO tech4lifeapps
  • 885
  • 1
  • 12
  • 31
GPH
  • 1,111
  • 6
  • 29
  • 49

2 Answers2

0

You cannot return something now that hasn't been loaded yet. With other words, you cannot simply use that companyList list outside the onDataChange() function because it will always be empty due the asynchronous behaviour of this function. This means that by the time you are trying to use that list outside that function, the data hasn't finished loading yet from the database and that's why is not accessible.

A quick solve for this problem would be to use that list only inside the onDataChange() function, otherwise I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding. It is for Android but the same principle applies.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • The companyList must be put outside the onDataChange() function, because fun generateData() must return a companyList. I am beginner and may made a lot of mistake. Can you show me how to do it? – GPH Jun 08 '18 at 14:34
  • Outside that method is empty. You want to use it outside, check my answer from the post. Have you try it? – Alex Mamo Jun 08 '18 at 14:44
0

When you add data to the list, you need to let the adapter know that its data set change. Only then will it repaint the view.

This means that at the end of your onDataChange you should call notifyDataSetChanged. Something like:

override fun onDataChange(dataSnapshot: DataSnapshot) {
    val td = dataSnapshot.value as HashMap<*, *>

    for (key in td.keys){
        val post = td[key] as HashMap<*, *>

        ...

        println(companyReg.nodeID)
        println(companyReg.address)


        companyList.add(companyReg)
    }

    adapter.notifyDataSetChanged()
}

This most likely means that you'll have to make the adapter a member field of the class, so that it's accessible in onDataChange().

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • I added qponAdapter(companyList).notifyDataSetChanged() just before the return inside the fun generateData(), but it also display 0 record – GPH Jun 08 '18 at 14:26
  • I don't know what `qponAdapter()` is, but it looks like you're generating a new adapter there. You need to call `notifyDataSetChanged` on the adapter you created in `onActivityCreated` and that you associated with `qponRecyclerView`. – Frank van Puffelen Jun 08 '18 at 14:30