Например, у меня есть список проблем. У каждой проблемы есть владелец uid. С помощью этого uid я должен найти нужных пользователей и отобразить его имя и фотографию. Я делаю это с помощью компонента архитектуры ViewModel:
issues.forEach { IssueRepository().getIssueOwner(it.owner).observe(this, Observer { }) }
Метод getIssueOwner:
fun getIssueOwner(uid: String): MutableLiveData<UserEntity> { val user: MutableLiveData<UserEntity> = MutableLiveData() val usersReference = FirebaseDatabase.getInstance().reference.child("users") val query = usersReference.orderByKey().equalTo(uid).limitToFirst(1) query.addValueEventListener(object : ValueEventListener { override fun onCancelled(p0: DatabaseError?) { } override fun onDataChange(dataSnapshot: DataSnapshot?) { if (dataSnapshot == null) { return } dataSnapshot.children.forEach { val name = it.child("displayName").value user.postValue(UserEntity(name)) } } }) return user }
Но я уверен, что этот подход неверен. Не могли бы вы дать мне совет, как я должен построить архитектуру моего приложения?
Эта:
val query = usersReference.orderByKey().equalTo(uid).limitToFirst(1)
Получает точно такие же результаты, как это намного проще:
val userReference = usersReference.child(uid)
Единственное различие между ними состоит в том, что первый фрагмент дает вам снимок со списком одного элемента, а второй фрагмент дает вам снимок с помощью всего элемента.
val userReference = usersReference.child(uid) userReference.addValueEventListener(object : ValueEventListener { override fun onCancelled(error: DatabaseError?) { throw error.toException() // don't ignore errors } override fun onDataChange(dataSnapshot: DataSnapshot?) { if (dataSnapshot.exists() val name = dataSnapshot.child("displayName").value user.postValue(UserEntity(name)) } } })
Обратите внимание, что вы по-прежнему не можете вернуть пользователя из метода getIssueOwner
. Это связано с тем, что данные загружаются из Firebase асинхронно, и к тому моменту, когда выполняется ваш оператор return
, onDataChange
еще не был вызван.
Я рекомендую вам прочитать некоторые из этих предыдущих вопросов по этой теме, чтобы узнать больше об асинхронном характере Firebase (и большей части современной сети):