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

查看:28
本文介绍了如何在节点 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天全站免登陆