Как я могу вызвать несколько функций, используя одну и ту же транзакцию Firestore в AndroidAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как я могу вызвать несколько функций, используя одну и ту же транзакцию Firestore в Android

Сообщение Anonymous »

Мне нужно вызвать несколько функций, используя один и тот же объект транзакции. Вариант использования — когда мне нужно убедиться, что все функции выполняются эффективно или нет, например, при переводе денег. Мне нужно убедиться, что баланс пользователя уменьшен, Баланс другого пользователя увеличивается, и история этого обмена денег сохраняется. (Это не приложение для реальных денег, не спрашивайте, почему я делаю это на стороне клиента).
Мой вопрос: эта функция выполняется (список функций ) иногда дает соответствующие результаты, иногда он пропускает некоторые функции ИЛИ я не уверен, но данные в базе данных Firestore говорят сами за себя. Иногда они написаны частично, а иногда и полностью.

Код: Выделить всё

fun execute(functions: List Unit>) {
if (_loadingState.value == LoadingState.Loading) return //Avoid double tapping
_loadingState.value = LoadingState.Loading
viewModelScope.launch {
try {
Firebase.firestore.runTransaction { transaction ->
for (function in functions) {
function(transaction)
}
}.addOnSuccessListener {
_loadingState.value = LoadingState.Success
}.addOnFailureListener {
_loadingState.value =
LoadingState.Error("Failed, Error occurred: ${it.message}")
}
} catch (e: Exception) {
_loadingState.value = LoadingState.Error("Failed, Error occurred: ${e.message}")
}
}
}
Следует ли удалить viewModelScope.launch, следует ли поместить возвращаемое значение в блок runTransaction. Мне нужно фактическое решение, поскольку я сказал, что проблема не предсказуема, поэтому для тестирования/отладки мне нужно экспериментировать с реальными данными, и даже после 10–30 вызовов могут появиться частичные записи транзакций.

Код: Выделить всё

fun assignSender(user: User, order: Order) {
if (user.userID.isBlank() || user.name.isBlank() || user.userID == order.sendBy) return
_actionStarted = true
val functions = listOf Unit> { transaction ->
assignSenderTransaction(transaction, user, order)
HistoryViewModel.saveHistory(transaction, HistoryViewModel.toHistoryAssign(order, user))
}
execute(functions)
}
Это один из примеров, когда я вызываю выполнение В основном я использую функцию выполнения с функцией, которая принимает хотя бы один аргумент транзакции. Другие функции:

Код: Выделить всё

 private fun assignSenderTransaction(transaction: Transaction, user: User, order: Order) {
val orderRef = firestore
.collection(Collections.ORDERS).document(order.id)
val updates =
mapOf("sendBy" to user.userID, "senderName" to user.name, "senderPhone" to user.phone)
transaction.update(orderRef, updates)
}

fun saveHistory(transaction: Transaction, history: History) {
val historyRef = Firebase.firestore
.collection(Collections.HISTORYS).document(history.id)
transaction.set(historyRef, history)
}
Все, что я делаю, это проверяю, что функции чтения запускаются перед написанием. В случае этой функции иногда история не записывается.
ОБНОВЛЕНИЕ:
Здесь есть эта функция после того, как я просмотрел весь код и обнаружил, что не соответствует правилу Firestore, составляющему 1 запись в секунду. А также некоторые поля полей карты могут иметь специальные символы, такие как продукты={"key+-":5, что может не соответствовать принципу работы точечного синтаксиса< /p>

Код: Выделить всё

fun incrementStock(
transaction: Transaction,
userID: String,
userName: String,
products: HashMap,
increase: Boolean
) {
val stockRef = Firebase.firestore.collection(Collections.STOCKS).document(userID)
for ((product, quantity) in products) {
transaction.update(
stockRef,
"products.$product",
FieldValue.increment(if (increase) quantity.toLong() else -quantity.toLong())
)
}
HistoryViewModel.saveHistory(
transaction,
HistoryViewModel.toHistory(products, userID, userName, increase)
)
}
Может ли транзакция завершиться успешно, даже если некоторые операции записи в цикле завершатся неудачно, если документ был обновлен хотя бы один раз? Если ключ в карте продуктов содержит такие символы, как _-=+, не удастся ли записать файл map.fieldOfMap? Если да, гарантирует ли это, что транзакция также не удастся?

Подробнее здесь: https://stackoverflow.com/questions/790 ... in-android
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»