繁体   English   中英

如何使我的 firebase 数据库的结果实时持续更新?

[英]How to make my result from firebase database continuously update at realtime?

我一直在构建一个应用程序,允许用户检索和删除他自己在 Firebase 数据库上注册的一些物品,这是我的 function 允许的(谢谢,Zeeshan):

override suspend fun getAllOnline(): MutableStateFlow<ResourceState<List<DocModel>>> {
    auth = FirebaseAuth.getInstance()
    val docList: MutableList<DocModel> = suspendCoroutine { continuation ->
        database
            .child(auth.currentUser!!.uid)
            .addValueEventListener(object : ValueEventListener {
                override fun onDataChange(snapshot: DataSnapshot) {
                    val docList: MutableList<DocModel> = mutableListOf()
                    for (docs in snapshot.children) {
                        val doc = docs.getValue(DocModel::class.java)
                        docList.add(doc!!)
                    }
                    continuation.resume(docList) << Line 34 where the error happens
                }

                override fun onCancelled(error: DatabaseError) {
                    continuation.resume(emptyList<DocModel>() as MutableList<DocModel>)
                }
            })
    }
    return if (docList.isNotEmpty()) {
        MutableStateFlow(ResourceState.Success(docList))
    } else {
        MutableStateFlow(ResourceState.Empty())
    }
}

问题是我无法在应用程序不崩溃的情况下删除文件。 抛出的错误是:

2023-01-01 19:45:12.816 5637-5637/com.tods.docreminder E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tods.docreminder, PID: 5637
java.lang.IllegalStateException: Already resumed
    at kotlin.coroutines.SafeContinuation.resumeWith(SafeContinuationJvm.kt:44)
    at com.tods.docreminder.feature.doc.data.repository.remote.DocFirebaseRepositoryImpl$getAllOnline$docList$1$1.onDataChange(DocFirebaseRepositoryImpl.kt:34)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
    at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
    at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7844)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)

据我了解,问题是我正在从 web 中删除一些内容并且它没有实时更新,所以它无法在我的回收站视图上显示更改(该项目是使用滑动删除的,因此 UI 应该自动更新以显示给用户的新结果)。
我如何能够从这个 function 实施这个实时更新?
任何需要的代码,只要告诉我,我会尽快更新。
谢谢您的支持。

谢谢,亚历克斯:我使用这个存储库作为示例: 存储库
这是存储库的更新结果:

override suspend fun getAllOnline(): MutableStateFlow<ResourceState<List<DocModel>>> {
    auth = FirebaseAuth.getInstance()
    val docList = mutableListOf<DocModel>()
    val docs = database.child(auth.currentUser!!.uid).get().await()
    for(document in docs.children) {
        val doc = document.getValue(DocModel::class.java)
        docList.add(doc!!)
    }
    return if (docList.isNotEmpty()) {
        MutableStateFlow(ResourceState.Success(docList))
    } else {
        MutableStateFlow(ResourceState.Empty())
    }
}

现在我可以删除了,我将使用 Resource State 消息正确管理异常,将答案发送给用户。

编辑:
现在收到异常:

override suspend fun getAllOnline(): MutableStateFlow<ResourceState<List<DocModel>>> {
    auth = FirebaseAuth.getInstance()
    val docState: MutableStateFlow<ResourceState<List<DocModel>>>
    val docList = mutableListOf<DocModel>()
    docState = try {
        val docs = database.child(auth.currentUser!!.uid).get().await()
        for(document in docs.children) {
            val doc = document.getValue(DocModel::class.java)
            docList.add(doc!!)
        }
        if(docList.isNotEmpty()) {
            MutableStateFlow(ResourceState.Success(docList))
        } else {
            MutableStateFlow(ResourceState.Empty())
        }
    } catch(e: StorageException) {
        MutableStateFlow(ResourceState.Error(e.message))
    }
    return docState
}

还有我的 ResourceState class 如果有帮助的话:

sealed class ResourceState<T>(
    val data: T? = null,
    val message: String? = null
) {
    class Success<T>(data: T?): ResourceState<T>(data)
    class Error<T>(message: String?, data: T? = null): ResourceState<T>(data, message)
    class Loading<T>: ResourceState<T>()
    class Empty<T>: ResourceState<T>()
}

希望它有帮助 =)

错误来自这行代码:

 continuation.resume(docList) << Line 34 where the error

协程是oneShot resume,所以如果你收到数据你第一次resume,第二次会崩溃,使用FlowChannel来接收多个响应

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM