数据:
- products
- -L74Pc7oVY22UsCETFBv
- name: "gjwj"
- category: "hreggrrg"
- location: "vjhiwehifwe"
- price: 44
- color: fassaf
- -L74uJ7oVYcVNyCteFBz
- name: "uygfwh"
- category: "hhhjwwwom"
- location: "pervrr"
- price: 33
- color: yrtrr
......................
我在节点products
中有很多产品,超过1000种产品。我可以在ListView
中显示所有内容。我想只向用户显示一个独特的随机数,例如高亮显示,但不是全部下载,只有一个。
代码:
ValueEventListener v = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot child : dataSnapshot.getChildren()) {
String name = (String) child.child("name").getValue().toString();
Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show();
//How to get?????
}
}
@Override
public void onCancelled(DatabaseError databaseError) {}
};
FirebaseDatabase.getInstance().getReference().addListenerForSingleValueEvent(v);
如何在节点Firebase中获取唯一随机产品?
答案 0 :(得分:2)
嗯,这里有一些关于SOF的好答案但是是分开的,所以我会尝试用两种方法回答你的问题。


但首先,在编写一些代码之前,我可以告诉你这段代码没有用,因为你在引用中是一个孩子,这是 products
,显然假设 products
节点是您的Firebase数据库根目录的直接子项。
实际答案:


假设您的数据库结构如下所示(其中 products
节点是Firebase数据库的直接子节点):
Firebase -root
 |
 ---产品
 |
 --- productIdOne
 | |
 | ---名称:“gjwj”
 | |
 | ---类别:“hreggrrg”
 | |
 | ---位置:“vjhiwehifwe”
 | |
 | ---价格:44
 | |
 | ---颜色:“fassaf”
 |
 --- productIdTwo
 | |
 | ---名称:“uygfwh”
 | |
 | ---类别:“hhhjwwwom”
 | |
 | ---位置:“pervrr”
 | |
 | ---价格:33
 | |
 | ---颜色:“yrtrr”
 |
 --- //依旧



 要获得随机产品,请使用以下代码:
&#xA; &#XA;<代码>列表与LT;字符串&GT; randomProductList = new ArrayList&lt;&gt;();&#xA; ListView listView =(ListView)findViewById(R.id.list_view);&#xA; ArrayAdapter arrayAdapter = new ArrayAdapter&lt;&gt;(context,android.R.layout。 simple_list_item_1,randomProductList);&#xA; listView.setAdapter(arrayAdapter);&#xA; DatabaseReference rootRef = FirebaseDatabase.getInstance()。getReference();&#xA; DatabaseReference productsRef = rootRef.child(“products”); //添加了对.child(“products”)的调用&#xA; ValueEventListener valueEventListener = new ValueEventListener(){&#xA; @越权#XA; public void onDataChange(DataSnapshot dataSnapshot){&#xA;列表与LT;字符串&GT; productList = new ArrayList&lt;&gt;();&#xA; for(DataSnapshot ds:dataSnapshot.getChildren()){&#xA; String name = ds.child(“name”)。getValue(String.class);&#xA; productList.add(名称);&#XA; }&#XA;&#XA; int productCount = productList.size();&#xA; int randomNumber = new Random()。nextInt(productCount);&#xA;&#xA; randomProductList.add(productList.get(randomNumber)); //将随机产品添加到列表&#xA; arrayAdapter.notifyDatasetChanged();&#XA; }&#XA;&#XA; @越权#XA; public void onCancelled(DatabaseError databaseError){&#xA; Log.d(TAG,“错误:”,task.getException()); //不要忽视错误!&#xA; }&#xA;};&#xA; productsRef.addListenerForSingleValueEvent(valueEventListener);&#xA;&#xA;&#xA;
为了获得所有产品,你需要循环遍历 products
节点的所有子节点。因此,必须调用 child(“products”)
。
如果您想要一个以上的随机产品,那么您可以创建一个循环并在 randomProductList
中添加任意数量的随机产品。
这称为经典解决方案,您可以将其用于包含的节点只有少数记录,但如果您害怕获取大量数据,那么我会建议您使用第二种方法。这还需要通过添加名为 productIds
的新节点对数据库进行一些更改。您的数据库结构应如下所示:
Firebase-root&#xA; |&#XA; ---产品&#xA; | |&#XA; | --- productIdOne&#xA; | | |&#XA; | | --- //详情&#xA; | |&#XA; | --- productIdTwo&#xA; | |&#XA; | --- //详情&#xA; | &#XA; --- productIds&#xA; |&#XA; --- productIdOne:true&#xA; |&#XA; --- productIdTwo:true&#xA; |&#XA; --- //等等&#xA;
&#xA;&#xA; 正如您在问题中提到的,如果您想避免下载整个产品
节点包含具有所有属性的所有产品,您必须创建一个名为 productIds
的单独节点。因此,要获得单个产品,您只需要下载仅包含产品ID的简单节点。
这种做法称为非规范化(复制数据),并且Firebase的常见做法。为了更好地理解,我重新命令您看到此视频,使用Firebase数据库进行非规范化是正常的。
&#xA;&#xA;但请记住,在这个新创建的节点中添加随机产品的方式,就像你需要在不再需要时删除它们一样。
&#xA;&#xA;因此,要获取随机产品,您需要两次查询数据库。请参阅下面的代码:
&#xA;&#xA; DatabaseReference rootRef = FirebaseDatabase.getInstance()。getReference();&#xA; DatabaseReference productIdsRef = rootRef.child(“productIds “);&#xA; ValueEventListener valueEventListener = new ValueEventListener(){&#xA; @越权#XA; public void onDataChange(DataSnapshot dataSnapshot){&#xA;列表与LT;字符串&GT; productIdsList = new ArrayList&lt;&gt;();&#xA; for(DataSnapshot ds:dataSnapshot.getChildren()){&#xA; String productId = ds.getKey();&#xA; productIdsList.add(的productId);&#XA; }&#XA;&#XA; int productCount = productIdsList.size();&#xA; int randomNumber = new Random()。nextInt(productCount);&#xA;&#xA; DatabaseReference productIdRef = rootRef.child(“products”)。child(productIdsList.get(randomNumber));&#xA; ValueEventListener eventListener = new ValueEventListener(){&#xA; @越权#XA; public void onDataChange(DataSnapshot dataSnapshot){&#xA; String name = dataSnapshot.child(“name”)。getValue(String.class);&#xA; Log.d(“TAG”,名称);&#xA; }&#XA;&#XA; @越权#XA; public void onCancelled(DatabaseError databaseError){&#xA; Log.d(TAG,“错误:”,task.getException()); //不要忽视错误!&#xA; }&#XA; };&#XA; productIdRef.addListenerForSingleValueEvent(事件监听);&#XA; }&#XA;&#XA; @越权#XA; public void onCancelled(DatabaseError databaseError){&#xA; Log.d(TAG,“错误:”,task.getException()); //不要忽视错误!&#xA; }&#xA;};&#xA; productIdsRef.addListenerForSingleValueEvent(valueEventListener);&#xA;
&#xA;&#xA; 当您对Firebase数据库执行查询时,可能会有多个结果。所以 dataSnapshot
包含这些结果的列表。即使只有一个结果, dataSnapshot
对象也会包含一个结果的列表。