Android Firestore объединит 2 коллекции в представление переработчика

У меня есть коллекция пользователей с uId, именем, фотографией

У меня есть коллекция посещений с uId, userId, location

У меня есть recyclerview, в котором я хочу показать местоположение с именем пользователя и фотографией

Могу ли я использовать тип поля ссылки? Если да, то как Firestore узнает, что нужно связать visits.userId == users.uId ?

Может быть, мне сначала нужно запросить все посещения, а затем запросить соответствующего пользователя, но 2 вещи:

  1. Это означает многократные запросы.

  2. Я не понял, как собрать объединенную коллекцию в адаптер, который основан на одном запросе?

Пожалуйста посоветуй Спасибо

текущий код

visitsList = db.collection("visitsList");
Query query = visitsList.whereEqualTo("userId",prefs.getString("id","")).orderBy("visitDate", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<AVisit> options = new FirestoreRecyclerOptions.Builder<AVisit>().setQuery(query, AVisit.class).build();
adapter = new VisitsListAdapter(options, VisitsListActivity.this);
RecyclerView rv = findViewById(R.id.rvVisitsList);
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(adapter);

Код представляет собой простой запрос из коллекции, не знаю, как получить имя и фотографию из поля userId в этой коллекции.

Для # 2) если у вас возникли проблемы с работой кода, поделитесь минимальный код, который воспроизводит проблему (прочитайте ссылку, пожалуйста, так как она невероятно полезна).

Frank van Puffelen 23.02.2019 16:36

Обновлено. Текущий код простой запрос из коллекции.

Amos 23.02.2019 16:41

Итак, вы используете FirebaseUI и задаетесь вопросом, как отображать данные из профиля пользователя в списке посещений. Для будущих вопросов: это было бы отличным названием. :) У меня нет готового кода для этого, но я ожидаю два основных варианта: 1) загрузить дополнительный пользовательский документ в populateView или с пользовательской parseSnapshot реализацией, 2) продублировать соответствующие пользовательские данные в коллекции посещений ( что вполне нормально для баз данных NoSQL). Также см. ответ Алекса здесь: stackoverflow.com/q/48756129.

Frank van Puffelen 23.02.2019 17:03
1
3
1 231
1

Ответы 1

Can I use the reference field type?

Да, вы можете использовать поле ссылки.

If so, how will Firestore know to link visits.userId == users.uId ?

Результаты Firestore всегда поступают из одной коллекции (на данный момент). Он не присоединяется автоматически к документу из коллекции пользователей, когда вы читаете из коллекции посещений. Вам придется сделать это самостоятельно.

Это действительно означает, что вы будете выполнять несколько операций чтения, но часто это не так медленно, как вы думаете. См. Google Firestore – как получить документ по нескольким идентификаторам за одну поездку?


Обновление: для отображения данных из профиля пользователя в списке посещений есть два основных варианта:

  1. загрузите дополнительный пользовательский документ в populateView или с помощью нестандартная parseSnapshot реализация.

  2. дублировать соответствующие пользовательские данные в коллекции посещений (что вполне нормально в базах данных NoSQL). Также см. ответ Алекса здесь: индексированный запрос с FirestoreRecyclerAdapter.

Так как же мне здесь помогает эталонное поле? Я делаю простой visitsList.whereEqualTo("userId",prefs.getString("id","")) и получаю информацию из коллекции посещений. Как "интегрировать" имя и фото из коллекции пользователей в адаптер? (см. обновленный код). Также имя короткая строка, изображение намного тяжелее, хотя здесь я могу запросить одного пользователя за раз, но вопрос интеграции (в адаптер) все еще актуален.

Amos 23.02.2019 16:45

См. stackoverflow.com/questions/46568850/… для объяснения инженера Firestore о типе ссылочного поля.

Frank van Puffelen 23.02.2019 16:57

Спасибо за ссылку. Ссылка указывает на конкретный collection.document, поэтому его объяснение немного сбивает с толку (комментарии там также отражают эту путаницу). В любом случае, очевидно, что это не имеет отношения к моему вопросу. Спасибо

Amos 23.02.2019 17:13

Я проверю вариант populateview, который вы предложили. Размышляя об этом, не должен ли я использовать событие onBindViewHolder, где все данные на самом деле «связаны» с просмотрщиком?

Amos 23.02.2019 17:17

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

Frank van Puffelen 23.02.2019 19:13

Пока я пытаюсь добавить это в addSnapshotListener.onEvent. Это позволит избежать прерывания графического интерфейса (например, в onBindViewHolder). Скоро обновится.

Amos 23.02.2019 20:04

Я в замешательстве, похоже, единственное место, где я могу это сделать, это onBindView, где у меня есть доступ ко всем свойствам viewHolder.

Amos 23.02.2019 22:00

Другие вопросы по теме