回调流等待收集其内部流
我正在我的Android应用程序中实现Firestore,我想知道如何使该代码在使用该程序之前等待其内部流程。 Trip.tripdays在wher表达式中的响应之后的时间填充了数据。
override fun getTrips(idUser: String): Flow<Response<List<Trip>>> = callbackFlow {
val trips = mutableListOf<Trip>()
tripsRef
.whereEqualTo(ID_USER, idUser)
.get()
.addOnSuccessListener { snapshot ->
for (doc in snapshot.documents) {
val trip = doc.toObject(Trip::class.java)
if (trip != null) {
trip.id = doc.id
CoroutineScope(Dispatchers.IO).launch {
val tripDaysFlow = tripDaysRepository.getTripDays(trip.id)
tripDaysFlow.collect() {
when (it) {
is Response.Loading -> {
Log.d("FirestoreTripsRepositoryImpl", "Loading")
}
is Response.Success -> {
trip.tripDays = it.data
}
is Response.Error -> {
trySend(Response.Error(it.message)).isFailure
}
is Response.Message -> {
trySend(Response.Message(it.message))
}
}
}
}
trips.add(trip)
}
}
trySend(Response.Success(trips)).isSuccess
}
.addOnFailureListener {
trySend(Response.Error(it.message ?: it.toString())).isFailure
}
.await()
awaitClose()
}
override fun getTripDays(idTrip: String): Flow<Response<List<TripDay>>> = callbackFlow {
val tripDaysRef = tripsRef.document(idTrip).collection(TRIP_DAYS_REF)
val tripDays = mutableListOf<TripDay>()
tripDaysRef
.get()
.addOnSuccessListener {
for (doc in it.documents) {
val tripDay = doc.toObject(TripDay::class.java)
if (tripDay != null) {
tripDay.id = doc.id
tripDays.add(tripDay)
}
}
trySend(Response.Success(tripDays)).isSuccess
}
.addOnFailureListener {
trySend(Response.Error(it.message ?: it.toString())).isFailure
}
.await()
awaitClose ()
}
sealed class Response<out T> {
object Loading : Response<Nothing>()
data class Success<out T>(val data: T) : Response<T>()
data class Error(val message: String) : Response<Nothing>()
data class Message(val message: String) : Response<Nothing>()
}
一个很大的发射:
override fun getTrips(idUser: String): Flow<Response<List<Trip>>> = callbackFlow {
val trips = mutableListOf<Trip>()
tripsRef
.whereEqualTo(ID_USER, idUser)
.get()
.addOnSuccessListener { snapshot ->
launch {
Log.d("launch", "launched")
for (doc in snapshot.documents) {
if (doc.id == "kJJFEatove5mxw4P70uq")
continue
val trip = doc.toObject(Trip::class.java)
if (trip != null) {
trip.id = doc.id
val tripDaysFlow = tripDaysRepository.getTripDays(trip.id)
tripDaysFlow.collect {
when (it) {
is Response.Loading -> trySend(Response.Loading)
is Response.Success -> trip.tripDays = it.data
is Response.Error -> trySend(Response.Error(it.message)).isFailure
is Response.Message -> trySend(Response.Message(it.message))
}
}
trips.add(trip)
}
}
trySend(Response.Success(trips)).isSuccess
close()
}
}
.addOnFailureListener {
trySend(Response.Error(it.message ?: it.toString())).isFailure
close()
}
awaitClose()
}
可以使它在没有完整的重建的情况下使其正常工作会很酷,但是让我知道我的方法是否完全错误。干杯!
I'm implementing firestore in my android app and I was wondering how I can make this code wait for its inner flow to be collected before running with the program. The trip.tripDays in the when expression is getting populated with data a time after Response.Success with my trips is already sent.
override fun getTrips(idUser: String): Flow<Response<List<Trip>>> = callbackFlow {
val trips = mutableListOf<Trip>()
tripsRef
.whereEqualTo(ID_USER, idUser)
.get()
.addOnSuccessListener { snapshot ->
for (doc in snapshot.documents) {
val trip = doc.toObject(Trip::class.java)
if (trip != null) {
trip.id = doc.id
CoroutineScope(Dispatchers.IO).launch {
val tripDaysFlow = tripDaysRepository.getTripDays(trip.id)
tripDaysFlow.collect() {
when (it) {
is Response.Loading -> {
Log.d("FirestoreTripsRepositoryImpl", "Loading")
}
is Response.Success -> {
trip.tripDays = it.data
}
is Response.Error -> {
trySend(Response.Error(it.message)).isFailure
}
is Response.Message -> {
trySend(Response.Message(it.message))
}
}
}
}
trips.add(trip)
}
}
trySend(Response.Success(trips)).isSuccess
}
.addOnFailureListener {
trySend(Response.Error(it.message ?: it.toString())).isFailure
}
.await()
awaitClose()
}
override fun getTripDays(idTrip: String): Flow<Response<List<TripDay>>> = callbackFlow {
val tripDaysRef = tripsRef.document(idTrip).collection(TRIP_DAYS_REF)
val tripDays = mutableListOf<TripDay>()
tripDaysRef
.get()
.addOnSuccessListener {
for (doc in it.documents) {
val tripDay = doc.toObject(TripDay::class.java)
if (tripDay != null) {
tripDay.id = doc.id
tripDays.add(tripDay)
}
}
trySend(Response.Success(tripDays)).isSuccess
}
.addOnFailureListener {
trySend(Response.Error(it.message ?: it.toString())).isFailure
}
.await()
awaitClose ()
}
sealed class Response<out T> {
object Loading : Response<Nothing>()
data class Success<out T>(val data: T) : Response<T>()
data class Error(val message: String) : Response<Nothing>()
data class Message(val message: String) : Response<Nothing>()
}
One big launch:
override fun getTrips(idUser: String): Flow<Response<List<Trip>>> = callbackFlow {
val trips = mutableListOf<Trip>()
tripsRef
.whereEqualTo(ID_USER, idUser)
.get()
.addOnSuccessListener { snapshot ->
launch {
Log.d("launch", "launched")
for (doc in snapshot.documents) {
if (doc.id == "kJJFEatove5mxw4P70uq")
continue
val trip = doc.toObject(Trip::class.java)
if (trip != null) {
trip.id = doc.id
val tripDaysFlow = tripDaysRepository.getTripDays(trip.id)
tripDaysFlow.collect {
when (it) {
is Response.Loading -> trySend(Response.Loading)
is Response.Success -> trip.tripDays = it.data
is Response.Error -> trySend(Response.Error(it.message)).isFailure
is Response.Message -> trySend(Response.Message(it.message))
}
}
trips.add(trip)
}
}
trySend(Response.Success(trips)).isSuccess
close()
}
}
.addOnFailureListener {
trySend(Response.Error(it.message ?: it.toString())).isFailure
close()
}
awaitClose()
}
Would be cool to make it work without a complete rebuild, but let me know if my approach is completely wrong. Cheers!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论