Как получить уникальный случайный продукт в узле Firebase? - PullRequest
0 голосов
/ 18 мая 2018

Данные:

- 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?

1 Ответ

0 голосов
/ 18 мая 2018

Хорошо, здесь есть несколько хороших ответов о SOF, но они разделены, поэтому я попытаюсь ответить на ваш вопрос двумя подходами.

Но прежде всего, прежде чем писать код, я могу сказать вамчто этот код не работает, потому что в вашей ссылке вы не указали дочерний элемент, равный products, очевидно, предполагая, что узел products является прямым дочерним элементом корня базы данных Firebase.

фактический ответ:

Предполагая, что ваша структура базы данных выглядит следующим образом (в которой узел products является прямым потомком вашей базы данных Firebase):

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

Чтобы получитьПроизвольный продукт, используйте следующий код:

List<String> randomProductList = new ArrayList<>();
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 productCount = productList.size();
        int randomNumber = new Random().nextInt(productCount);

        randomProductList.add(productList.get(randomNumber)); //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") является обязательным.

Если вам нужно более одного случайного продукта, вы можете создать цикл и добавить столько случайных продуктов, сколько вы хотите, в свой randomProductList.

Это называется классическим решением, и вы можете использовать его для узлов, которые содержат только несколько записей, но если вы боитесь получать огромное количество данных, я рекомендую вам этот второй подход.Это также включает небольшие изменения в вашей базе данных путем добавления нового узла с именем productIds.Структура вашей базы данных должна выглядеть следующим образом:

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

Итак, как вы упомянули в своем вопросе, если вы хотите избежать загрузки всего узла products, который содержит все продукты со всеми свойствами, вы должнысоздайте отдельный узел с именем productIds.Таким образом, чтобы получить один продукт, вам нужно всего лишь загрузить простой узел, который содержит только идентификаторы продукта.

Эта практика называется денормализацией (дублирование данных) и является обычной практикой, когда речь идет о Firebase.Для лучшего понимания, я рекомендую вам посмотреть это видео, Денормализация нормальная с базой данных Firebase .

Но помните, как вы добавляете случайные продукты в этот новый созданный узел,таким же образом вам нужно удалить их, когда они больше не нужны.

Таким образом, чтобы получить случайный продукт, вам нужно дважды запросить базу данных.Пожалуйста, смотрите код ниже:

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 productCount = productIdsList.size();
        int randomNumber = new Random().nextInt(productCount);

        DatabaseReference productIdRef = rootRef.child("products").child(productIdsList.get(randomNumber));
        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 будет содержать список из одного результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...