Как получить LiveData списка элементов, соответствующих содержимому другого LiveData из Firestore?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как получить LiveData списка элементов, соответствующих содержимому другого LiveData из Firestore?

Сообщение Anonymous »

Мое приложение для Android использует Firebase Firestore. У меня есть коллекция пользователей и коллекция достижений. У каждого достижения есть список владельцев, который является идентификатором документа из коллекции пользователей. В моей ViewModel у меня есть объект LiveData, и я хотел бы иметь объект LiveData, содержащий точных пользователей, перечисленных в атрибуте владельцев объекта Достижение.
Что работает на данный момент:

Код: Выделить всё

class AchievementDetailsViewModel(private val achievementId: String) : ViewModel() {
private val _achievement: MediatorLiveData = MediatorLiveData()
public val achievement: LiveData get() = _achievement

init {
fetchAchievementData()
}

private fun fetchAchievementData() {
viewModelScope.launch {
val achievementLiveData = AchievementService.getAchievement(achievementId)
_achievement.addSource(achievementLiveData) {
_achievement.value = it
}
}
}

}

object AchievementService {
fun getAchievement(id: String): LiveData {
return Firebase.firestore.collection(Collections.ACHIEVMENTS).document(id)
.snapshots()
.map { s -> s.toObject(Achievement::class.java)!! }
.asLiveData()
}
}
Таким образом я могу получить доступ к достижению и обновлениям LiveData, как и ожидалось.
Чтобы добавить список пользователей в ViewModel , я попытался добавить следующий код:

Код: Выделить всё

class AchievementDetailsViewModel(private val achievementId: String) : ViewModel() {
private val _achievement: MediatorLiveData = MediatorLiveData()
public val achievement: LiveData get() = _achievement
private val _owners: MediatorLiveData = MediatorLiveData(emptyList())
public val owners: LiveData get() = _owners

init {
fetchAchievementData()
fetchOwnerData()
}

private fun fetchOwnerData() {
viewModelScope.launch {
_achievement.observeForever { achievement ->
val ownersLiveData = UserService.getUsers(achievement.ownerIds)
_owners.addSource(ownersLiveData) { _owners.value = it }
}
}
}
}

object UserService {
fun getUsers(userIds: List): LiveData {
return Firebase.firestore.collection(Collections.USERS)
.whereIn(FieldPath.documentId(), userIds)
.snapshots()
.map { s -> s.toObjects(User::class.java) }
.asLiveData()
}
}
Это не работает, поскольку при первом вызове getUsers параметр userIds представляет собой пустой список. Это недопустимый параметр для вызоваwhereIn, который ожидает, что список будет содержать только действительные идентификаторы документов. Я попытался передать listOf("") в вызовwhereIn в случае пустого списка, что привело к следующему исключению: java.lang.IllegalArgumentException: неверный запрос. При запросе с помощью FieldPath.documentId() вы должны указать действительный идентификатор документа, но это пустая строка.. Затем попробовал изменить метод следующим образом:

Код: Выделить всё

fun getUsers(userIds: List): LiveData {
if (userIds.isEmpty()) {
return MutableLiveData(ListOf())
}
return Firebase.firestore.collection(Collections.USERS)
.whereIn(FieldPath.documentId(), userIds)
.snapshots()
.map { s -> s.toObjects(User::class.java) }
.asLiveData()
}
Проблема здесь в том, что при первом вызове этой функции она возвращает LiveData пустого списка, и этот объект LiveData всегда будет представлять этот неизменный список. пустой список. Я пробовал еще несколько вещей, но эти попытки также сводились к тому, что где-то было условие, обрабатывающее случай пустого списка, и я всегда получал LiveData пустого списка. Ждать, пока _achievement.value.ownerIds.isNotEmpty(), к сожалению, невозможно, так как список владельцев достижения может оказаться пустым. Что мне здесь не хватает? Нет ли простого способа обработать случай пустого списка в вызовеwhereIn?
Изменить: чтобы уточнить, ожидаемое поведение относится к LiveData> для обновления на основе содержимого LiveData Я понимаю, почему моя реализация не дает такого результата, но я не знаю, как добиться ожидаемого поведения. Я предполагаю, что проблема больше связана с неправильным использованием LiveData, чем с Firestore.

Подробнее здесь: https://stackoverflow.com/questions/783 ... ther-lived
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»