Firebase云函数在启动时是否会像Firestore调用一样从安卓系统的主线程中运行
对于Firestore数据库调用,默认情况下处理后台线程。
即我们需要使用后台线程来使用firebase检索数据吗
Firebase数据库客户端在主线程外执行所有网络和磁盘操作。
Firebase数据库客户端调用主线程上对代码的所有回调。
因此,数据库的网络和磁盘访问并不是启动自己的线程或使用后台任务的理由。但是,如果在回调中执行磁盘、网络I/O或CPU密集型操作,则可能需要自己在主线程外执行这些操作。
观察
Firebase Cloud函数使用Kotlin协程在Android的ViewModel中的IO
线程上启动,并在Main
线程上返回。但是,如果默认情况下云函数未在主线程上运行,则不需要flowOn(Dispatchers.IO)
和withContext(Dispatchers.Main)
来指定线程。
SomeViewModel.kt
fun someMethod() {
repository.someCloudFunction().onEach { resource ->
withContext(Dispatchers.Main) {
// Do something with returned resource here.
}
}.flowOn(Dispatchers.IO).launchIn(viewModelScope)
}
SomeRepository.kt
fun someCloudFunction(contentSelected: FeedViewEventType.ContentSelected) = flow {
try {
val content = contentSelected.content
FirebaseFunctions.getInstance(firebaseApp(true))
.getHttpsCallable("SOME_CLOUD_FUNCTION").call(
hashMapOf(
BUILD_TYPE_PARAM to BuildConfig.BUILD_TYPE,
CONTENT_ID_PARAM to content.id,
CONTENT_TITLE_PARAM to content.title,
CONTENT_PREVIEW_IMAGE_PARAM to content.previewImage))
.continueWith { task ->
(task.result?.data as HashMap<String, String>)
}
// Use 'await' to convert callback to coroutine.
.await().also { response ->
// Do something with response here.
}
} catch (error: FirebaseFunctionsException) {
// Do something with error here.
}
}
Expect
如果默认情况下云函数不在主线程上运行,则可以安全地删除在IO
线程上运行云函数并在Main
线程上返回响应的显式调用。
SomeViewModel.kt
fun someMethod() {
repository.someCloudFunction().onEach { resource ->
// Do something with returned resource here.
}.launchIn(viewModelScope)
}
执行时:
FirebaseFunctions.getInstance(...).getHttpsCallable(...).call()
调用异步返回,访问函数的工作发生在SDK管理的非主线程中。你不能改变这种行为,在不同的协同程序范围内启动它并不会真正改变任何事情。
当您添加带有continueWith
的延续时,默认情况下回调发生在主线程上。
直到您对返回的Task调用await()
,才在用于启动Task的协同程序范围内发生任何事情。当您等待重用时,结果会交给协同程序进行更多处理。
对于您的代码,我不想尝试使用延续,因为将结果反弹到主线程在这里根本没有帮助。只需等待调用返回的Task,然后对协程中的原始结果执行您想要的操作。
您链接的答案是关于Firebase Realtime Database客户端的,它与Firebase Functions客户端是分开的。
也就是说,所有Firebase客户端都应该遵循相同的规则,所以我希望Functions客户端也能在主线程之外执行所有网络I/O。
这不是你看到的吗?
Android函数SDK的代码位于开源SDK中。