kotlin 数据未保存到实时数据库(Firebase)

vnjpjtjt  于 2023-04-07  发布在  Kotlin
关注(0)|答案(1)|浏览(139)

我已连接到Firebase实时数据库:

数据:

data class Settings(
    val light_on: Boolean = false,
    val door_open: Boolean = false,
    val window_open: Boolean = false
)

仓库编码:

class SettingsRepository @Inject constructor() {
    private val database: FirebaseDatabase = DatabaseModule.getFirebaseDatabaseInstance()

    fun getSettings() : Flow<HomeSettings?> {
        return callbackFlow {
            val dataRef = database.getReference("settings")

            val listener = dataRef.addValueEventListener(object: ValueEventListener {
                override fun onDataChange(snapshot: DataSnapshot) {
                   trySend(snapshot.getValue(HomeSettings::class.java))
                }

                override fun onCancelled(error: DatabaseError) {
                    cancel()
                }
            })

            awaitClose { dataRef.removeEventListener(listener) }
        }
    }

    fun createData(settings: Settings) : Flow<Settings> = flow {
        database.reference.child("settings").setValue(settings).await()
    }

    fun updateLightState(settings: Settings) : Flow<Settings> = flow {
        database.reference.child("settings").setValue(settings).await()
    }

    fun updateDoorState(settings: Settings) : Flow<Settings> = flow {
        database.reference.child("settings").setValue(settings).await()
    }

    fun updateWindowState(settings: Settings) : Flow<Settings> = flow {
        database.reference.child("settings").setValue(settings).await()
    }
}

用法:

fun createData(){
    settingsRepository.createData(settings.value)
}

LaunchedEffect(scope) {
    viewModel.createData()
}

它只是不显示任何在实时数据库Firebase控制台在线在谷歌,这是奇怪的。没有错误打印在调试输出在Android Studio。我只是不明白为什么这不工作。

编辑:规则没有问题,已更改。

**EDIT:**这个是我自己做的,在控制台显示的是引用的名称,不是项目,需要手动设置ID,还是做一些配置修改?

fun insert(item: Settings) : Flow<ResultResponse<String>> = callbackFlow {
        trySend(ResultResponse.Loading)

        reference.push().setValue(item)
            .addOnCompleteListener {
                if(it.isSuccessful)
                    trySend(ResultResponse.Success("Data inserted successfully"))
            }
            .addOnFailureListener {
                trySend(ResultResponse.Failure(it))
                cancel()
            }

        awaitClose { close() }
    }
cbeh67ev

cbeh67ev1#

以下方法:

fun createData(settings: Settings) : Flow<Settings> = flow {
    database.reference.child("settings").setValue(settings).await()
}

定义为返回一个Flow。首先,不建议使用这种方法返回一个Flow,因为您只是向数据库添加一些数据。这种方法应该是一个简单的挂起函数。当您需要按顺序发送多个值时,使用Flow。
除此之外,你正在创建一个Flow,但你从来没有收集结果。所以在我看来,要将数据添加到实时数据库,我会创建一个响应类:

sealed class Response<out T> {
    data class Success<out T>(
        val data: T
    ): Response<T>()

    data class Failure(
        val e: Exception?
    ): Response<Nothing>()
}

repository类中的suspend方法如下所示:

suspend fun createData(settings: Settings): Response<Boolean> {
    return try {
        database.reference.child("settings").setValue(settings).await()
        Response.Success(true)
    } catch (e: Exception) {
        Response.Failure(e)
    }
}

然后我会使用viewModelScope从ViewModel类调用它:

var response by mutableStateOf<Response<Boolean>>(Response.Success(false))
    private set

fun createData(settings: Settings) = viewModelScope.launch {
    response = repo.createData(settings)
}

在屏幕内部,我会用途:

when(val response = viewModel.response) {
    is Success -> Log.d(TAG, "Data added successfully.")
    is Failure -> Log.d(TAG, "Failed with: ${response.e?.message}")
}

还有一个建议,总是尝试处理错误。

相关问题