【发布时间】:2021-04-20 23:41:48
【问题描述】:
我正在使用 Kotlin 编写我的第一个应用程序,并且正在使用 Firestore 和 Firebase 存储。在删除文档的过程中,我想删除存储中文档引用的所有文件(因为在我的情况下它是对它们的唯一引用)。如果存储删除失败,我想中止文档删除,以避免存储中的孤立文件。我还想在“一个任务”中做所有事情,以允许正确显示进度条。我的简化代码如下所示:
fun deleteItem(id: String): Task<Void>? {
val deleteTask = deleteTaleMedia(id)
continueWithTaskOrInNew(deleteTask) { task ->
if (task?.isSuccessful != false) { ... }
}
}
fun deleteItemMedia(id: String): Task<Void>? =
getItem(id)?.continueWithTask { task ->
if (task.isSuccessful)
task.result?.toObject(ItemModel::class.java)?.let { deleteFiles(it.media) }
else ???
}
fun deleteFiles(filesList: List<String>): Task<Void>? {
var deleteTask: Task<Void>? = null
for (file in filesList) deleteTask = continueWithTaskOrInNew(deleteTask) { task ->
if (task?.isSuccessful != false) deleteFile(file)
else task
}
return task
}
fun deleteFile(fileName: String) = Firebase.storage.getReferenceFromUrl(fileName).delete()
fun getItem(id: String): Task<DocumentSnapshot>? {
val docRef = userDocRef?.collection(COLLECTION_PATH)?.document(id)
return docRef?.get()
?.addOnCompleteListener { ... }
}
fun <ResultT, TContinuationResult> continueWithTaskOrInNew(
task: Task<ResultT>?,
continuation: (Task<ResultT>?) -> Task<TContinuationResult>?
) = task?.continueWithTask { continuation.invoke(task) } ?: continuation.invoke(null)
data class ItemModel(
@DocumentId val id: String = "",
var title: String = "",
var media: List<String> = listOf()
)
我的问题来自deleteItemMedia 函数(末尾的“???”)。如果 get 任务失败,我想返回一个任务,告诉我的 deleteItem 函数中止删除 (task.isSuccessful == false)。我无法返回获取任务本身(将代码中的“???”替换为“任务”),因为它的类型(Task<DocumentSnapshot>)与删除任务的类型(Task<Void>)不同。我无法返回null,因为null 在根本没有媒体的情况下返回,这对我来说是有效的情况(应该删除文档)。有没有办法创建一个新的“失败的任务”?
【问题讨论】:
标签: firebase kotlin google-cloud-firestore firebase-storage google-tasks-api