Как получить массив из Firestore? - PullRequest
0 голосов
/ 08 мая 2018

enter image description here

У меня вышеупомянутая структура данных хранится в Cloud Firestore. Я хочу сохранить dungeon_group, который представляет собой массив строк, хранящихся в Firestore.

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

Я могу добиться этого в Swift следующим образом, но не знаю, как сделать то же самое в Android.

// Swift

Firestore.firestore().collection("dungeon").document("room_en").getDocument { (document, error) in
        if let document = document {
            let group_array = document["dungeon_group"] as? Array ?? [""]
            print(group_array)
        }

    }

// JAVA Android

    FirebaseFirestore.getInstance().collection("dungeon").document("room_en").get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                DocumentSnapshot document = task.getResult();
                String group_string= document.getData().toString();
                String[] group_array = ????

                Log.d("myTag", group_string);
            }
        });

Вывод на консоль: {dungeon_group = [3P, Срочно, Вызов миссии, Снизился, Сотрудничество, Ежедневно, Технический, Обычный]}

Ответы [ 3 ]

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

Если вы хотите получить весь массив dungeon_group, вам нужно выполнить итерацию по Map следующим образом:

Map<String, Object> map = documentSnapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
    if (entry.getKey().equals("dungeon_group")) {
        Log.d("TAG", entry.getValue().toString());
    }
}

Но учтите, что даже если объект dungeon_group хранится в базе данных в виде массива, entry.getValue() возвращает ArrayList, а не массив.

Лучший подход для вас будет, если вы рассмотрите эту альтернативную структуру базы данных, в которой каждый group является ключом в Map, а все значения установлены в логическое значение true:

dungeon_group: {
    3P: true,
    Urgent: true,
    Mission Chalange: true
    //and so on
}

Используя эту структуру, вы также сможете запрашивать ее, основываясь на свойстве, существующем на карте dungeon_group, в противном случае, как в официальной документации :

Хотя Cloud Firestore может хранить массивы, it does not support запрашивает элементы массива или обновляет отдельные элементы массива.

Изменить 13 августа 2018 г .:

Согласно обновленной документации относительно членства в массиве , теперь возможно фильтровать данные на основе значений массива, используя метод whereArrayContains(). Простым примером будет:

CollectionReference citiesRef = db.collection("cities");
citiesRef.whereArrayContains("regions", "west_coast");

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

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

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

DocumentSnapshot document = task.getResult();
List<String> dungeonGroup = (List<String) document.get("dungeon_group");

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

public class Dungeon {

    @PropertyName("dungeon_group")
    private List<String> dungeonGroup;

    public Dungeon() {
        // Must have a public no-argument constructor
    }

    // Initialize all fields of a dungeon
    public Dungeon(List<String> dungeonGroup) {
        this.dungeonGroup = dungeonGroup;
    }

    @PropertyName("dungeon_group")
    public List<String> getDungeonGroup() {
        return dungeonGroup;
    }

    @PropertyName("dungeon_group")
    public void setDungeonGroup(List<String> dungeonGroup) {
        this.dungeonGroup = dungeonGroup;
    }
}

Помните, что вы можете использовать Annotation @PropertyName, чтобы избежать вызова ваших переменных так же, как ваше значение в базе данных. Делая это таким образом, наконец, вы можете просто сделать:

DocumentSnapshot document = task.getResult();
Dungeon dungeon= toObject(Dungeon.class);

Надеюсь, что это поможет вам! Удачного кодирования!

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

Когда вы вызываете DocumentSnapshot.getData () , он возвращает карту.Вы просто вызываете toString () на этой карте, которая даст вам дамп всех данных в документе, и это не особенно полезно.Вам необходимо получить доступ к полю dungeon_group по имени:

DocumentSnapshot document = task.getResult();
List<String> group = (List<String>) document.get("dungeon_group");
  • edit: синтаксическая ошибка при вводе типа
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...