Проблема запроса базы данных Firebase в реальном времени - PullRequest
0 голосов
/ 24 марта 2020

У меня есть база из 800+ предметов, и я хочу отфильтровать их по редкости. С «одиночной» редкостью (например, только с «легендарной» редкостью) я могу легко это сделать, но проблема возникает при попытке объединить две редкости (например, редкость «event & basi c»).

Это метод, который я использую:

 private void loadFirebaseData(String rarity1, String rarity2) {

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Outfits");
    reference.keepSynced(true);

    Query query = reference.orderByChild("rarity").startAt(rarity1).endAt(rarity2);
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            arrayCosmetics = new ArrayList<>();

            for (DataSnapshot data : dataSnapshot.getChildren()) {
                Cosmetics cosmetics = data.getValue(Cosmetics.class);
                arrayCosmetics.add(cosmetics);
            }

            cosmeticsAdapter = new CosmeticsAdapter(getActivity(), arrayCosmetics);
            cosmeticsAdapter.setHasStableIds(true);

            recyclerView.setVisibility(View.VISIBLE);
            recyclerView.setAdapter(cosmeticsAdapter);

            Collections.shuffle(arrayCosmetics, new Random(3));

            rootView.findViewById(R.id.progressBar).setVisibility(View.GONE);

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });
}

И называя его так: loadFirebaseData("basic", "event");

Итак, проблема в том, что он загружает меня все раритеты от алфавита "b" вплоть до "е "(например," basi c "," classi c "," common "," elite "," epi c ") и, очевидно, я хочу только" basi c "и" event "

База данных имеет следующую структуру:

"01" : {
"available" : "Wanderer Crate",
"created" : "20191023T021358Z",
"id" : 11010006,
"image" : "https://prod-live-front.playbattlegrounds.com/images/item_176/11010006.png",
"info" : "Drop Chance: 5.00%",
"marketable" : true,
"name" : "Dirty Tank Top (White)",
"rarity" : "common",
"slot" : "torso" }

"02" : {
"available" : "Wanderer Crate",
"created" : "20191023T021358Z",
"id" : 11010014,
"image" : "https://prod-live-front.playbattlegrounds.com/images/item_176/11010014.png",
"info" : "Drop Chance: 5.00%",
"marketable" : true,
"name" : "Tank Top (Charcoal)",
"rarity" : "common",
"slot" : "torso" }

Правила Firebase:

 "Outfits": {
  ".indexOn": ["rarity"]
}

Можно достичь того, что я хочу, не загружая всю базу данных в одну большую ArrayList<>() ?

Если у меня есть целое ArrayList<>(), я могу сделать что-то вроде этого:

private void rarityFilter(String rarity1, String rarity2) {

    ArrayList<Cosmetics> newListCosmetics = new ArrayList<>();

    for (Cosmetics cosmetics : arrayCosmetics) {
        String name = cosmetics.getRarity().toLowerCase();
        if (name.contains(rarity1) || name.contains(rarity2))
            newListCosmetics.add(cosmetics);
    }
    cosmeticsAdapter.setFilter(newListCosmetics);
}

Но не плохо ли для производительности загрузить целые ArrayList<>()?

1 Ответ

0 голосов
/ 24 марта 2020

Похоже, вы пытаетесь загрузить узлы, у которых свойство rarity имеет значение event или значение basic. База данных Firebase Realtime не поддерживает такие запросы ИЛИ, и не существует много хороших способов их решения.

Наиболее распространенные обходные пути:

  • Добавление свойства для каждой комбинации, которую вы хотите разрешить, например, "rarity_event_or_basic": true, а затем отфильтруйте ее. Это не очень хорошо, поскольку требует большого количества свойств и становится трудно индексировать.
  • Выполните отдельный запрос для каждого значения и объедините результаты в коде приложения. Это довольно эффективно, если речь идет о производительности, поскольку Firebase может выполнять их параллельно. Но код, как правило, немного запутан, и если вы хотите объединить его с фильтром пределов, вы, скорее всего, в конечном итоге получите больше данных, чем необходимо.
  • Если значения лексикографически близки друг к другу, вы можете использовать условие диапазона. Например, ref.orderByChild("rarity").startAt("basic").endAt("event").

См. Также:

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