【问题标题】:Firestore update snapshotListener replies are out of order even when waiting for .get()即使在等待 .get() 时,Firestore 更新快照侦听器的回复也是无序的
【发布时间】:2018-10-12 19:56:15
【问题描述】:

运行一个 hello-world,将一些连续的真/假值写入 Firestore 数据库,目标是保持本地变量与云同步。

即使每个update() 调用在使用get() 启动下一个调用之前等待,回调事件似乎也出现了问题

我写“假”、“真”、“真” 但响应是“真”、“假”、“真”

即使是陌生人,有时也会有 3 个响应,即使我只提出了 2 个请求。下次我启动该应用程序时,是否有可能出现排队?如果是这样,有什么方法可以确保在关机前刷新?

我担心我的本地应用程序可能会对最近的值产生错误的印象。

import com.google.auth.oauth2.GoogleCredentials
import com.google.cloud.firestore.FirestoreOptions
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val firestoreOptions = FirestoreOptions.newBuilder()
            .setCredentials(GoogleCredentials.fromStream(
                    ClassLoader.getSystemClassLoader().getResourceAsStream("serviceAccountKey.json")))
            .setTimestampsInSnapshotsEnabled(true)
            .build()
    val db = firestoreOptions.service!!

    val docRef = db.collection("users").document("tmpUser").collection("devices").document("tmpDevice")
    docRef.addSnapshotListener { snapshot, _ ->
        (snapshot?.data ?: mapOf()).forEach { key, value ->
            println("  RESPONSE: '$key'='$value'")
        }
    }
    println("Listening...")

    val writeResultFuture2 = docRef.update(mapOf("running" to false))
    println("REQUEST 'false' at ${writeResultFuture2.get().updateTime}")

    val writeResultFuture3 = docRef.update(mapOf("running" to true))
    println("REQUEST 'true' at ${writeResultFuture3.get().updateTime}")

    val writeResultFuture4 = docRef.update(mapOf("running" to true))
    println("REQUEST 'true' at ${writeResultFuture4.get().updateTime}")

    delay(5_000)
    println("Stopping.")
}

输出:

Listening...
  RESPONSE: 'running'='true'
  RESPONSE: 'running'='false'
REQUEST 'false' at 2018-10-12T21:07:25.530943000Z
REQUEST 'true' at 2018-10-12T21:07:25.686950000Z
  RESPONSE: 'running'='true'
REQUEST 'true' at 2018-10-12T21:07:25.686950000Z
Stopping.

【问题讨论】:

  • 你能用这段代码打印出你最近一次运行的日志吗?
  • @ToddKerpelman 已编辑以包含输出。

标签: firebase kotlin google-cloud-firestore


【解决方案1】:

所以简短的回答是这似乎按设计工作。

首先,请记住,当您创建 updateListener 时,它不仅会在更新时触发,而且还会在第一次使用数据库中已经存在的任何数据时触发。 (这通常是您想要的——它使您的代码更容易编写,因为您只需将处理程序创建为“来自数据库的所有数据”处理程序,无论是来自初始检索还是更新。)所以这就是为什么你会得到第一个“真实”的回应。

第二个“错误”响应来自您应用的第一个更新。

第三个“真实”响应来自您应用的第二个更新

第四个“真”响应永远不会被触发,因为客户端 SDK 通常足够聪明,如果数据库中的数据与已存在的数据完全相同,则不会再次调用处理程序。我猜如果将第三次更新调用更改为“也许”之类的内容,那么您会看到第四次响应。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2021-04-07
    • 2022-01-09
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2021-07-02
    • 2019-07-31
    相关资源
    最近更新 更多