androidfirebasekotlinfirebase-realtime-database

How to properly listen to child changes in FirebaseDatabase


I am trying to listen to my database child changes, in my case it is orders.

Below is a picture of my database, where
ODdPag... Is the uid of my customer

Lu-_1A is just .push random order naming

I can provide my code but it is confusing and not working, because i can only access Orders and not its next child.

Now I want to list all my orders and lister for changes in sub children (in order names) not uid.

I am using:

val db = FirebaseDatabase.getInstance.reference
val ref = db.child("/Orders/")

ref.addChildEventListener(object: ChildEventListener {

            override fun onChildAdded(p0: DataSnapshot, p1: String?) {

                ringtone.play()

                itemListTable.clear()
                p0.children.forEach {
                    it.child("order").children.forEach{ item ->
                        val newData = item.getValue(itemListData::class.java) ?: return
                        newData.itemName = item.key!!
                        newData.orderKey = it.key!!
                        itemListTable.add(newData)

                    }
                    val data = it.getValue(itemRowData::class.java) ?: return
                    adapter.add(itemRow(data.phoneNumber,data.time,data.locationLat,data.locationLong,data.optionalAddress,data.optionalNote,data.totalPrice,itemListTable,it.key))
                }
            }


            override fun onChildChanged(p0: DataSnapshot, p1: String?) {

                Log.d("ac1234","$p0")
                    p0.child("order").children.forEach{ item ->
                        Log.d("ac1234","1")
                        val newData = item.getValue(itemListData::class.java) ?: return
                        Log.d("ac1234","2")
                        newData.itemName = item.key!!
                        newData.orderKey = p0.key!!
                        itemListTable.add(newData)}


                    val data = p0.getValue(itemRowData::class.java) ?: return
                    adapter.add(itemRow(data.phoneNumber,data.time,data.locationLat,data.locationLong,data.optionalAddress,data.optionalNote,data.totalPrice,itemListTable,p0.key))

            }
class itemRowData(val phoneNumber :String = "",val time :String = "",val locationLat :Double = 0.0,val locationLong :Double = 0.0,val optionalAddress :String = "",val optionalNote :String = "",val totalPrice :String = "")
class itemListData(var itemName: String = "" ,val totalQuantity: String = "",val totalPrice :Long = 0,var orderKey :String = "")

Logcat: 1 and 2 are not called

P0 shows 4 rows full of all data every time I send an order


Solution

  • I want all orders from all users, that is my problem. I cant reference to every ("/Orders/uid") to listen to child changes

    To get all orders of all users, you should use a ValueEventListener, like in the following lines of code:

    val rootRef = FirebaseDatabase.getInstance().reference
    val ordersRef = rootRef.child("Orders")
    val valueEventListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            for (uidDataSnapshot in dataSnapshot.children) {
                for (orderDataSnapshot in uidDataSnapshot.children) {
                    val newData = orderDataSnapshot.getValue(itemListData::class.java)
                    itemListTable.add(newData)
                }
            }
        }
    
        override fun onCancelled(databaseError: DatabaseError) {
            Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
        }
    }
    ordersRef.addValueEventListener(valueEventListener)
    

    See, in order to get each order of each user, you should iterate twice, once to get the uidDataSnapshot and then to get the orderDataSnapshot object.