Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase和Kotlin合作项目_Firebase_Kotlin_Google Cloud Firestore_Firebase Storage - Fatal编程技术网

Firebase和Kotlin合作项目

Firebase和Kotlin合作项目,firebase,kotlin,google-cloud-firestore,firebase-storage,Firebase,Kotlin,Google Cloud Firestore,Firebase Storage,我有这个静态(伴生对象)函数从Firebase Firestore下载事件信息,并从Firebase Storage下载事件图像: fun downloadEventInformationAndImages() { FirebaseFirestore.getInstance().collection("events").document(downloadedEventID) .get().addOnSuccessListener { snap -> //Downl

我有这个静态(伴生对象)函数从Firebase Firestore下载事件信息,并从Firebase Storage下载事件图像:

fun downloadEventInformationAndImages() {
    FirebaseFirestore.getInstance().collection("events").document(downloadedEventID)
    .get().addOnSuccessListener { snap ->

    //Download Event Information Here
    //Do stuff

    GlobalScope.launch(Dispatchers.Main) {
        //Download Event Images Here
        val downloadEventImage = FirebaseStorage.getInstance().reference.child("Images/Events/$eventID/eventPhoto.jpeg")
                            .getBytes(1024 * 1024).asDeferred()
        val downloadEventFounderImage = FirebaseStorage.getInstance().reference.child("Images/Users/$founderID/profilePhoto.jpeg")
                            .getBytes(1024 * 1024).asDeferred()

        try {
           val downloadedImages = mutableListOf<ByteArray>(
                                downloadEventImage.await(),
                                downloadEventFounderImage.await())
            // Update stuff on UI
        } catch(e: StorageException) {
            // Error handling
        }
     }.addOnFailureListener { exception ->
     // Error handling
     }
    }
}

它不起作用(它并没有等到Firebase完成下载——然后我将runBlocking移到函数内部,也不起作用)。如何避免使用GlobalScope?提前感谢。

您可以将函数编写为
CoroutineScope
扩展函数:

fun CoroutineScope.downloadEventInformationAndImages() {
    ...
    launch(Dispatchers.Main) {
    ...
}
并从ViewModel或其他具有范围的地方调用它:

uiScope.downloadEventInformationAndImages()

我在这里看到的最佳选择是将
CoroutineScope
作为
下载事件信息和图像的参数传递。那就是

fun downloadEventInformationAndImages(scope: CoroutineScope) {
  FirebaseFirestore.getInstance().collection("events").document(downloadedEventID)
  .get().addOnSuccessListener { snap ->

  //Download Event Information Here
  //Do stuff

    scope.launch(Dispatchers.Main) { ... }
  }
}

需要注意的一点是,您在这里启动的每个协同路由现在都是在您传入的范围内启动的,这意味着如果它失败或被取消,它还将取消任何父协同路由。要了解如何处理此问题,您应该查看文档中的。另一方面,您还可以使用
SupervisorJob
(在上面的文档链接中提到)构建您的
CoroutineScope
,其中子coroutines失败而不影响父级。最后,当拥有它的对象的生命周期结束时,清理
CoroutineScope
也是一种很好的做法。这将避免可能的内存泄漏。可以使用
scope.cancel()
scope.coroutineContext.cancelChildren()
完成清理。第一个终止作用域的作业(传播到所有子作业),第二个只取消可能存在的任何子作业。我建议你花一些时间阅读关于协同程序的文章甚至文档,因为有很多细微差别:)

你不能把一个与调用方生命周期相关的
CoroutineScope
作为
下载事件信息和图像的参数传递给调用方吗?嘿@ricardsteiocora!它是有效的-我很惊讶答案是这么简单-谢谢!:)由于我是Kotlin和Coroutines的新手,在将CoroutineScope作为参数(如内存泄漏等)传递时,有什么特别的事情需要注意吗?很高兴它起了作用:)我会在几分钟后写一个更详细的答案。你好,Andrei!非常感谢你的回答。因为我是Kotlin和Coroutines的新手,所以我无法实现您的答案(我认为我应该这样做)。但是里卡多在第一篇博文的评论中提出的方法对我来说是有效的。再次感谢你的回答。你好,梅廷。没问题:)扩展是非常有用的Kotlin特性。如果你想了解科特林,你总有一天会读到这篇文章的
fun downloadEventInformationAndImages(scope: CoroutineScope) {
  FirebaseFirestore.getInstance().collection("events").document(downloadedEventID)
  .get().addOnSuccessListener { snap ->

  //Download Event Information Here
  //Do stuff

    scope.launch(Dispatchers.Main) { ... }
  }
}