如何在Kotlin中基于唯一键值检索Firebase数据

时间:2019-12-17 13:27:23

标签: android firebase kotlin firebase-realtime-database android-recyclerview

我正在从Firebase数据库中获取所有"items"条目。 实际需要什么才能只给我特定unique key

的条目
ref = FirebaseDatabase.getInstance().getReference().child("Sales")
ref.addValueEventListener(object : ValueEventListener{
    override fun onCancelled(p0: DatabaseError) {
    }
    override fun onDataChange(p0: DataSnapshot) {
        ref.addListenerForSingleValueEvent(object : ValueEventListener {
            override fun onCancelled(p0: DatabaseError) {
            }
            override fun onDataChange(p1: DataSnapshot) {
                println("onDataChange")
                if (p0.exists()) {
                    list.clear()
                    for (h in p0.children) {
                        if (h.hasChild("items")) {
                            val generic: GenericTypeIndicator<ArrayList<Product>> =  object : GenericTypeIndicator<ArrayList<Product>>() {}
                            val items = h.child("items").getValue(generic)
                            items?.let { productList.addAll(it) }
                        }
                        val adapter = ReceiptItemsAdapter(applicationContext, productList)
                        rReceyclerView.adapter = adapter
                    }
                }
            }
        })
    }
})

我已经尝试过了,但是它没有用,也没有给出任何错误。

 ref = FirebaseDatabase.getInstance().getReference().child("Sales/-Lw37uyfuBA0AfTalp")

这是我的json文件

{
  "-Lw37uyfuBA0AfTalp": {
    "date": "14\/12\/2019",
    "discount": 0.24,
    "due": 0,
    "items": [
      {
        "pamount": 2.4,
        "pname": "Granola",
        "pprice": 2.4,
        "punit": 1
      }
    ],
    "paym": [
      {
        "paymentAmnt": 0.02,
        "paymentDesc": "Cash Payment :"
      },
      {
        "paymentAmnt": 2.14,
        "paymentDesc": "Card Payment :"
      }
    ],
    "subTotal": 2.4,
    "time": "11:16:42",
    "total": 2.16
  },
  "-Lw5Qx8sVdw3ZCMiXAL-": {
    "date": "14\/12\/2019",
    "discount": 1,
    "due": 0,
    "items": [
      {
        "pamount": 4.8,
        "pname": "Granola",
        "pprice": 2.4,
        "punit": 2
      },
      {
        "pamount": 2.6,
        "pname": "Brownie",
        "pprice": 2.6,
        "punit": 1
      },
      {
        "pamount": 2.6,
        "pname": "Brownie",
        "pprice": 2.6,
        "punit": 1
      }
    ],
    "name": "James Brown",
    "paym": [
      {
        "paymentAmnt": 3,
        "paymentDesc": "Cash Payment :"
      },
      {
        "paymentAmnt": 5,
        "paymentDesc": "Staff Markout :"
      },
      {
        "paymentAmnt": 1,
        "paymentDesc": "Card Payment :"
      }
    ],
    "subTotal": 10,
    "time": "22:03:07",
    "total": 9
  },
  "-Lw5T4TfYUTXsWKAndBx": {
    "date": "14\/12\/2019",
    "discount": 0.24,
    "due": -0.84,
    "items": [
      {
        "pamount": 2.4,
        "pname": "Granola",
        "pprice": 2.4,
        "punit": 1
      }
    ],
    "name": "James Brown",
    "paym": [
      {
        "paymentAmnt": 3,
        "paymentDesc": "Cash Payment :"
      }
    ],
    "subTotal": 2.4,
    "time": "22:12:26",
    "total": 2.16
  },
  "-Lw5UWguHS18IwWE6elT": {
    "date": "14\/12\/2019",
    "discount": 0.26,
    "due": -1.66,
    "items": [
      {
        "pamount": 2.6,
        "pname": "Brownie",
        "pprice": 2.6,
        "punit": 1
      }
    ],
    "name": "James Brown",
    "paym": [
      {
        "paymentAmnt": 4,
        "paymentDesc": "Cash Payment :"
      }
    ],
    "subTotal": 2.6,
    "time": "22:18:43",
    "total": 2.34
  },
  "-Lw5ypp5xJLJO53bjejk": {
    "date": "15\/12\/2019",
    "discount": 0,
    "due": -1.6,
    "items": [
      {
        "pamount": 2.4,
        "pname": "Granola",
        "pprice": 2.4,
        "punit": 1
      }
    ],
    "name": "James Brown",
    "paym": [
      {
        "paymentAmnt": 4,
        "paymentDesc": "Cash Payment :"
      }
    ],
    "subTotal": 2.4,
    "time": "00:35:32",
    "total": 2.4
  },
  "-LwANPC0UYCmTnqm7DRV": {
    "date": "15\/12\/2019",
    "discount": 1,
    "due": 0,
    "items": [
      {
        "pamount": 2.4,
        "pname": "Granola",
        "pprice": 2.4,
        "punit": 1
      },
      {
        "pamount": 2.6,
        "pname": "Brownie",
        "pprice": 2.6,
        "punit": 1
      },
      {
        "pamount": 2.4,
        "pname": "Granola",
        "pprice": 2.4,
        "punit": 1
      },
      {
        "pamount": 2.6,
        "pname": "Brownie",
        "pprice": 2.6,
        "punit": 1
      }
    ],
    "name": "James Brown",
    "paym": [
      {
        "paymentAmnt": 5,
        "paymentDesc": "Cash Payment :"
      },
      {
        "paymentAmnt": 4,
        "paymentDesc": "Card Payment :"
      }
    ],
    "subTotal": 10,
    "time": "21:05:43",
    "total": 9
  }
}

任何人都可以告诉我,我在哪里做错了?

谢谢。

编辑部分 .... 产品类别

data class Product(var pName: String = "", var pUnit: Int = 1, var pPrice: Double = 00.00, var pAmount: Double = 00.00) : Parcelable {
constructor(parcel: Parcel) : this(
    parcel.readString(),
    parcel.readInt(),
    parcel.readDouble(),
    parcel.readDouble()
)

override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeString(pName)
    parcel.writeInt(pUnit)
    parcel.writeDouble(pPrice)
    parcel.writeDouble(pAmount)
}

override fun describeContents(): Int {
    return 0
}

companion object CREATOR : Parcelable.Creator<Product> {
    override fun createFromParcel(parcel: Parcel): Product {
        return Product(parcel)
    }

    override fun newArray(size: Int): Array<Product?> {
        return arrayOfNulls(size)
    }
}

此外,该部分在这里尝试过。

        val rootRef = FirebaseDatabase.getInstance().reference
    val ref = rootRef.child("Sales").child("-LwIWKf-CTNTdwi4iMLU")
    val valueEventListener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            val product = dataSnapshot.getValue(Product::class.java)
            //println("pname : "+product?.pName)
            Log.d(TAG, product!!.pName)
        }

        override fun onCancelled(databaseError: DatabaseError) {
           // Log.d("TAG", databaseError.getMessage()) //Don't ignore errors!
        }
    }
    ref.addListenerForSingleValueEvent(valueEventListener)

还尝试了Peter的解决方案,它可以工作,但是我需要将“ items”作为ArrayList 谢谢

2 个答案:

答案 0 :(得分:2)

您应该执行以下操作:

ref = FirebaseDatabase.getInstance().getReference().child("Sales").child("-Lw37uyfuBA0AfTalp")

 ref.addValueEventListener(object : ValueEventListener{
        override fun onCancelled(p0: DatabaseError) {

        }

        override fun onDataChange(p0: DataSnapshot) {

                    println("onDataChange")
                    if (p0.exists()) {
                         val date = p0.child("date").getValue(String::class.java)
                         val discount = p0.child("discount").getValue(String::class.java)
                        }
                }
    })

这将为您提供唯一键下的数据

答案 1 :(得分:1)

  

实际上只需要给我一个特定唯一键的条目的必要条件

要从特定的唯一键(例如-Lw37uyfuBA0AfTalp)中获取条目,请使用以下代码行:

val rootRef = FirebaseDatabase.getInstance().reference
val ref = rootRef.child("Sales").child("-Lw37uyfuBA0AfTalp")
val valueEventListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        val product = dataSnapshot.getValue(Product::class.java)
        Log.d(TAG, product!!.time)
    }

    override fun onCancelled(databaseError: DatabaseError) {
        Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
    }
}
ref.addListenerForSingleValueEvent(valueEventListener)

您的logcat中的输出将是:

11:16:42

我刚刚添加了一条日志语句以查看它是否有效。

编辑:

根据您的评论,如果要获取产品列表,请使用以下代码行:

val rootRef = FirebaseDatabase.getInstance().reference
val salesRef = rootRef.child("Sales")
val valueEventListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        val productList = arrayListOf<Product>()
        for (ds in dataSnapshot.children) {
            val product = ds.getValue(Product::class.java)
            productList.add(product)
            Log.d(TAG, product!!.time)
        }
        //Do what you need to do with your list
    }

    override fun onCancelled(databaseError: DatabaseError) {
        Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
    }
}
salesRef.addListenerForSingleValueEvent(valueEventListener)