Запуск приветственного мира записи нескольких последовательных значений true / false в базу данных 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 отредактировал, чтобы включить вывод.

Итак, краткий ответ: похоже, это работает так, как задумано.
Во-первых, имейте в виду, что когда вы создаете updateListener, он будет запускаться не только при обновлениях, но и в первый раз с любыми данными, уже существующими в базе данных. (И это обычно то, что вы хотите - это значительно упрощает написание вашего кода, потому что вы просто создаете свой обработчик как обработчик «Все данные из базы данных», будь то первоначальное извлечение или обновление.) Итак, это почему вы получаете этот первый «истинный» ответ.
Второй «ложный» ответ - это первое применяемое вами обновление.
Третий «истинный» ответ - это второе обновление, которое вы применяете.
Четвертый «истинный» ответ никогда не запускается, потому что клиентский SDK обычно достаточно умен, чтобы не вызывать обработчик снова, если данные из базы данных в точности совпадают с данными, которые уже существуют. Я предполагаю, что если бы этот третий вызов обновления был изменен на что-то вроде «Может быть», то вы бы увидели четвертый ответ.
Можете ли вы распечатать журнал вашего последнего запуска с помощью этого кода?