【问题标题】:how retreive firebase data based on unique key value in Kotlin如何根据 Kotlin 中的唯一键值检索 Firebase 数据
【发布时间】:2020-04-10 00:25:26
【问题描述】:

我在这里从 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 的解决方案,但我需要将“项目”作为 ArrayList 谢谢

【问题讨论】:

  • 您说的是哪个列表?如我所见,您只需要一种产品,对吧?
  • 这里这个; val generic: GenericTypeIndicator&lt;ArrayList&lt;Product&gt;&gt; = object : GenericTypeIndicator&lt;ArrayList&lt;Product&gt;&gt;() {} val items = h.child("items").getValue(generic) items?.let { productList.addAll(it) }
  • 我不明白。您尝试获取单个产品或产品列表?
  • 产品列表。

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


【解决方案1】:

您应该执行以下操作:

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)
                        }
                }
    })

这将为您获取唯一键下的数据

【讨论】:

  • @DavidGreen 你试过答案了吗?
  • 感谢@PeterHaddad。它帮助很大。
【解决方案2】:

实际上需要它来只给我来自特定唯一键的条目

要从特定的唯一键获取条目,例如-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)

【讨论】:

  • 嗨@Alex,这并没有给我任何数据。我认为这是因为我拥有其余的代码。 if (h.hasChild("items")) { val generic: GenericTypeIndicator&lt;ArrayList&lt;Product&gt;&gt; = object : GenericTypeIndicator&lt;ArrayList&lt;Product&gt;&gt;() {} val items = h.child("items").getValue(generic) items?.let { productList.addAll(it) } } 通过使用此代码,我将所有产品条目作为 ArrayList,并稍后使用它显示在 recyclerview 中。因为在某些情况下,它会列出多个产品。
  • 但是如果你将这一行val product = dataSnapshot.getValue(Product::class.java) 更改为val time = dataSnapshot.child("time").getValue(String::class.java) 并记录Log.d(TAG, time),你会得到任何输出吗?
  • 还没有。在您的代码中,log.d 没有显示任何内容。它可能没有得到val product。如果我在此处键入其他内容,则会在日志中打印消息。我将在这部分的问题中进行编辑,并将添加我的product 类。
  • 谢谢@Alex Mamo,它不是那样工作的,但是在我编辑之后它工作了。这是一个很大的帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 2019-09-26
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-14
  • 1970-01-01
相关资源
最近更新 更多