首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Firebase:如何检查文档写入是否成功

Firebase:如何检查文档写入是否成功
EN

Stack Overflow用户
提问于 2020-09-16 14:46:22
回答 2查看 1K关注 0票数 0

我想检查我的数据库写入是否成功,以便向用户显示一条错误消息。

我目前的方法不起作用,因为它说“类型错配,需要的单元找到了EmailStatus”

现行方法

代码语言:javascript
复制
class EmailRepositoryImpl : EmailRepository {
    private val db = Firebase.firestore

    override fun sendEmail(email: Email): EmailStatus<Nothing> {
        db.collection("emails").document().set(email).addOnCompleteListener {
            if (it.isSuccessful) return@addOnCompleteListener EmailStatus.Success<Nothing>
            if (it.isCanceled) return@addOnCompleteListener EmailStatus.Error(it.exception!!)
        }
    }
}

状态密封级

代码语言:javascript
复制
sealed class EmailStatus<out T> {
    data class Success<out T>(val data: T) : EmailStatus<T>()
    data class Error(val exception: Exception) : EmailStatus<Nothing>()
}

写这样的东西有可能吗?据我所知,有一个通用的firebase error type,但我没有发现任何与科特林或安卓.

我很感激你的帮助,谢谢你

编辑

我尝试过获取文档,但我只是获得了null:(当我使用侦听器方法时,一切都很好)

接口

代码语言:javascript
复制
interface EmailRepository {
    suspend fun getEmail(): Flow<EmailEntity?>
}

接口实现

代码语言:javascript
复制
override suspend fun getEmail(): Flow<EmailEntity?> = flow {
    val result = db.collection("emailprice").document("Email").get().await()
    emit(result.toObject<EmailEntity>())
}

ViewModel

代码语言:javascript
复制
private val emailEntity = liveData<EmailEntity?>(Dispatchers.IO) {
    emailRepository.getCalibratePrice()
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-17 12:22:42

好的,这是最后的解决方案,感谢@Gastón Saillén和@Doug Stevenson:

EmailRepository

代码语言:javascript
复制
interface EmailRepository {
    fun sendEmail(email: Email): Flow<EmailStatus<Unit>>
}

EmailRepository实现

代码语言:javascript
复制
class EmailRepositoryImpl @Inject constructor(
    private val db: FirebaseFirestore
) : EmailRepository {

    override fun sendEmail(email: Email)= flow<EmailStatus<Unit>> {
        db.collection("emails").add(email).await()
        emit(EmailStatus.success(Unit))
    }.catch {
        emit(EmailStatus.failed(it.message.toString()))
    }.flowOn(Dispatchers.Main)

}

ViewModel

代码语言:javascript
复制
fun sendEmail(): LiveData<EmailStatus<Unit>> {
    val newEmail = createEmail()
    return emailRepository.sendEmail(newEmail).asLiveData()
}

片段

代码语言:javascript
复制
btn.setOnClickListener {
            viewModel.sendEmail().observe(viewLifecycleOwner) {
                when(it) {
                    is EmailStatus.Success -> {
                        valid = true
                        navigateTo(next, bundleNext)
                        Toast.makeText(requireContext(), "Success", Toast.LENGTH_SHORT).show()
                    }
                    is EmailStatus.Failure -> {
                        valid = false
                        Toast.makeText(requireContext(), "Failed ${it.message}", Toast.LENGTH_SHORT).show()
                    }
                }
            }
}

我目前唯一的问题是,我的“公平国家”并没有像它应该的那样运作。

如果用户没有互联网接入,它应该会失败。目前,对数据库的写入从未失败,Firebase只是等待直到用户能够访问internet。这里的问题是,当我多次单击时,写将被多次执行。但是我认为我必须在这里实现更多的逻辑,上面写的代码和现在一样好。

票数 0
EN

Stack Overflow用户

发布于 2020-09-16 14:51:33

问题是,addOnCompleteListener回调不返回任何内容(单元),您正在尝试从该作用域返回一个EmailStatus

你有三种方法:

  1. 创建一个接口,该接口将填充该值并将该EmailStatus向下返回到调用方层。
  2. 在完成对firebase的异步调用时,使用Coroutines来挂起此函数,然后返回该值
  3. 当数据准备好处理时,使用Flow提供数据

我认为完成这一次操作的最简单方法是使用Coroutines;我编写了一篇关于这个的文章

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63922560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档