如何在节点Firebase中获得唯一的随机产品? [英] How to get unique random product in node Firebase?

查看:86
本文介绍了如何在节点Firebase中获得唯一的随机产品?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据:

- 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中显示所有内容.我只想向用户显示一个唯一的随机变量,例如精彩集锦,但不希望全部下载,只能下载一个.

I have many products in node products, over 1000 products. I can display all in ListView. I want to display only one unique random to user, like highlights, but not to download all, only one.

代码:

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中获得唯一的随机产品?

How to get unique random product in node Firebase?

推荐答案

好吧,SOF上有一些很好的答案,但它们是分开的,所以我将尝试用两种方法回答您的问题.

Well, there are a few good answers here on SOF but are separated, so I will try to answer your question with two approaches.

但是首先,在编写一些代码之前,我可以告诉您该代码无法正常工作,因为您在参考中误认为了一个孩子,即products,显然假设products节点是直接子节点您的Firebase数据库根目录的子级.

But first of all, before writing some code, I can tell you that this code is not working because you are missig a child in your reference, which is products, obviously assuming that the products node is a direct child of your Firebase database root.

实际答案:

假设您的数据库结构如下所示(其中products节点是Firebase数据库的直接子级):

Assuming that your database structure looks like this (in which the products node is a direct child of your Firebase database):

Firebase-root
   |
   --- products
         |
         --- productIdOne
         |      |
         |      --- name: "gjwj"
         |      |
         |      --- category: "hreggrrg"
         |      |
         |      --- location: "vjhiwehifwe"
         |      |
         |      --- price: 44
         |      |
         |      --- color: "fassaf"
         |
         --- productIdTwo
         |      |
         |      --- name: "uygfwh"
         |      |
         |      --- category: "hhhjwwwom"
         |      |
         |      --- location: "pervrr"
         |      |
         |      --- price: 33
         |      |
         |      --- color: "yrtrr"
         |
         --- //And so on

要获取随机产品,请使用以下代码:

To get a random product, please use the following code:

ListView listView = (ListView) findViewById(R.id.list_view);
ArrayAdapter arrayAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, randomProductList);
listView.setAdapter(arrayAdapter);
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference productsRef = rootRef.child("products"); //Added call to .child("products")
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String> productList = new ArrayList<>();
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String name = ds.child("name").getValue(String.class);
            productList.add(name);
        }

        int productListSize = productList.size();
        List<String> randomProductList = new ArrayList<>();

        randomProductList.add(new Random().nextInt(productListSize)); //Add the random product to list
        arrayAdapter.notifyDatasetChanged();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, "Error: ", task.getException()); //Don't ignore errors!
    }
};
productsRef.addListenerForSingleValueEvent(valueEventListener);

为了获得所有产品,您需要遍历products节点的所有子级.因此,必须调用child("products").

In order to get all the products, you need to loop through all children of the products node. So a call to child("products") is mandatory.

如果您想要一个以上的随机产品,则可以创建一个循环,并在randomProductList中添加所需数量的随机产品.

If you want more then one random product, then you can create a loop and add as many random products as you want in your randomProductList.

这被称为经典解决方案,您可以将其用于仅包含少量记录的节点,但是如果您担心会获取大量数据,那么我建议您使用第二种方法.这还涉及通过添加名为productIds的新节点来对数据库进行一些更改.您的数据库结构应如下所示:

This is called the classic solution and you can use it for nodes that contain only a few records but if you are afraid of getting huge amount of data then I'll recommend you this second approach. This also involves a little change in your database by adding a new node named productIds. Your database structure should look like this:

Firebase-root
   |
   --- products
   |     |
   |     --- productIdOne
   |     |      |
   |     |      --- //details
   |     |
   |     --- productIdTwo
   |            |
   |            --- //details
   |      
   --- productIds
          |
          --- productIdOne: true
          |
          --- productIdTwo: true
          |
          --- //And so on

因此,正如您在问题中提到的那样,如果要避免下载包含所有具有所有属性的产品的整个products节点,则必须创建一个名为productIds的单独节点.因此,要获得一个产品,您只需下载一个仅包含产品ID的简单节点即可.

So as you mentioned in your question, if you want to avoid downloading the entire products node which contains all the products with all the properties, you have to create a separate node named productIds. So to get a single product, you'll need only to download a simple node that contains only the product ids.

这种做法称为非规范化(复制数据),是涉及Firebase的常见做法.为了更好地理解,我建议您观看此视频,使用Firebase数据库进行非规范化是正常的.

This practice is called denormalization (duplicating data) and is a common practice when it comes to Firebase. For a better understanding, i recomand you see this video, Denormalization is normal with the Firebase Database.

但是请记住,您将随机产品添加到这个新创建的节点中的方式与您在不再需要它们时需要将其删除的方式相同.

But rememebr, in the way you are adding the random products in this new created node, in the same way you need to remove them when there are not needed anymore.

因此,要获得随机产品,您需要查询数据库两次.请参见下面的代码:

So to get the random product, you need to query your database twice. Please see the code below:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference productIdsRef = rootRef.child("productIds");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        List<String> productIdsList = new ArrayList<>();
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String productId = ds.getKey();
            productIdsList.add(productId);
        }

        int productListSize = productList.size();
        List<String> randomProductList = new ArrayList<>(););

        DatabaseReference productIdRef = rootRef.child("products").child(productIdsList.get(new Random().nextInt(int productListSize));
        ValueEventListener eventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String name = dataSnapshot.child("name").getValue(String.class);
                Log.d("TAG", name);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d(TAG, "Error: ", task.getException()); //Don't ignore errors!
            }
        };
        productIdRef.addListenerForSingleValueEvent(eventListener);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.d(TAG, "Error: ", task.getException()); //Don't ignore errors!
    }
};
productIdsRef.addListenerForSingleValueEvent(valueEventListener);

当您对Firebase数据库执行查询时,可能会有多个结果.因此,dataSnapshot包含这些结果的列表.即使只有一个结果,dataSnapshot对象也会包含一个结果的列表.

When you execute a query against the Firebase Database, there will potentially be multiple results. So the dataSnapshot contains a list of those results. Even if there is only a single result, the dataSnapshot object will contain a list of one result.

这篇关于如何在节点Firebase中获得唯一的随机产品?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆