Как запустить транзакцию Firebase с помощью сопрограмм Kotlin?

# #firebase #kotlin #firebase-realtime-database #kotlin-coroutines

Вопрос:

Я пытаюсь запустить транзакцию Firebase под приостановленной функцией в Котлине, и я не вижу никакой документации об этом.

Я использую

 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.5.2'
 

для сопрограмм с firebase (например: setValue(*).await ()), но, похоже, для runTransaction(*)нет функции ожидания

 override suspend fun modifyProductStock(
    product: ProductModel,
    valueToModify: Long,
    replace: Boolean
) {
    CoroutineScope(Dispatchers.Main).launch {
        val restaurantId = authRepository.restaurantId.value ?: throw Exception("No restaurant!")

        val productId = product.id ?: throw Exception("No Product ID!")

        val reference = FirebaseDatabase.getInstance().getReference("database/$restaurantId").child("products")

        if (replace) {
            reference.child(productId).child("stock").setValue(valueToModify).await()
        } else {
            reference.child(productId).child("stock")
                .runTransaction(object : Transaction.Handler {

                    override fun doTransaction(p0: MutableData): Transaction.Result {
                        //any operation
                        return Transaction.success(p0)
                    }

                    override fun onComplete(p0: DatabaseError?, p1: Boolean, p2: DataSnapshot?) {
                    }

                })
        }
    }
}
 

Ответ №1:

Вы могли бы завернуть его в suspendCoroutine :

 val result: DataSnapshot? = suspendCoroutine { c ->
    reference.child(productId).child("stock")
        .runTransaction(object : Transaction.Handler {
            override fun doTransaction(p0: MutableData): Transaction.Result {
                //any operation
                return Transaction.success(p0)
            }
    
            override fun onComplete(error: DatabaseError?, p1: Boolean, snapshot: DataSnapshot?) {
                c.resume(snapshot)
            }
        })
}
 

Приостановить действие подпрограммы

Получает текущий экземпляр продолжения внутри функций приостановки и приостанавливает выполнение текущей сопрограммы.
В этой функции как Continuation.resume, так и Continuation.resumeWithException могут использоваться либо синхронно в одном и том же кадре стека, где выполняется функция приостановки, либо асинхронно позже в том же потоке или из другого потока выполнения.

Ответ №2:

Учитывая, что пример Kotlin в документации Firebase по транзакциям использует тот же стиль обратного вызова, что и у вас, действительно кажется, что там нет конкретной поддержки для совместных процедур.

Возможно, стоит опубликовать проблему в репозитории Android SDK, чтобы ее добавить, или услышать, почему она не была добавлена.