Android объединяет два вызова Firestore в один обратный вызов - PullRequest
0 голосов
/ 16 мая 2019

В настоящее время я запрашиваю коллекцию на Firestore по этой ссылке:

val missionsCollection = FirebaseFirestore.getInstance()
    .collection("/customers").document(user.customerId).collection("missions")
    .orderBy("deadline")
    .whereGreaterThanOrEqualTo("deadline", startDate)
    .whereLessThanOrEqualTo("deadline", endDate)
    .whereArrayContains("staffs", user.id)

Просто, чтобы прояснить ситуацию, в моем документе миссии, поля, соответственно:

дедлайн : временная метка
штабы : массив строк с идентификаторами штаба

Итак, что я сейчас получаю, это все миссии определенного периодавовремя ( на основе крайнего срока ), который принадлежит определенному персоналу .

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

Поскольку у меня нет методас именем .whereArrayIsEmpty("staffs"), я создал поле в своем документе с именем visibleToAllStaffs, которое является логическим полем, но у меня есть более глубокая проблема.Firebase не разрешит оператор OR.

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

Итак, мои вопросы:

1) Есть ли собственный способ (с использованием только firebase) для меня сгруппировать два запросакоторый выбирает данные из той же коллекции, имеющей только один обратный вызов для ошибки и один для успеха (где, в этом случае, успех принесет обе данные)?

2) Если нет, могу ли я решить это с помощью RxJava илиСопрограммы?Как?

РЕДАКТИРОВАТЬ

Просто приведу еще несколько объяснений, мой второй вызов будет:

val missionsCollection = FirebaseFirestore.getInstance()
    .collection("/customers").document(user.customerId).collection("missions")
    .orderBy("deadline")
    .whereGreaterThanOrEqualTo("deadline", startDate)
    .whereLessThanOrEqualTo("deadline", endDate)
    .whereEqualTo("visibleToAllStaffs", true)

Переменные missionsCollection являются объектами типа Запрос .На этих объектах я могу вызвать get() метод, который возвращает Task объект QuerySnapshot (Task<QuerySnapshot>)

С этим объектом Task<QuerySnapshot> я могудобавьте несколько обратных вызовов (например, успех и ошибка), например:


missionsCollection.get().addOnSuccessListener { documentSnapshot ->
    val missions = documentSnapshot.map { it.toObject(Mission::class.java) }
    // do something with the list
}.addOnFailureListener {
    // Do something
}

Моя самая большая проблема с сопрограммами была попытка объединить обратные вызовы, потому что я думаю, у меня будет что-то вроде этого:

.merge(getMissionsCollection(), getSecondMissionsCollection())
.addOnSuccessListener { documentSnapshot ->
    val missionsFromBothCalls = documentSnapshot.map { it.toObject(Mission::class.java) }
    // do something with the full list
}.addOnFailureListener {
    // Do something
}

но я не смог найти ни одного примера, подобного этому (где методы возвращают "наблюдаемый", а не нужный мне Список, и я застрял в том, как объединить их вместе.

1 Ответ

1 голос
/ 16 мая 2019

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

suspend fun getMissionsCollection() = FirebaseFirestore.getInstance()
     .collection("/customers").document(user.customerId).collection("missions")
     .orderBy("deadline")
     .whereGreaterThanOrEqualTo("deadline", startDate)
     .whereLessThanOrEqualTo("deadline", endDate)
     .whereArrayContains("staffs", user.id)
     .get().await().result

suspend fun getSecondCollection() = FirebaseFirestore.getInstance()
     .
     . 
     .
     .get().await().result

, а затем с помощью

launch {
   val missionCollection = getMissionsCollection()
   val secondCollection= getSecondCollection()

   // merge collections or whatever
}
...