You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无网络时如何保存Firebase Realtime Database数据并在联网后同步?

Kotlin Android 考勤应用Firebase离线同步实现方案

1. 启用Firebase Realtime Database内置离线持久化

在Application类的onCreate方法中初始化Firebase时开启磁盘持久化,Firebase会自动缓存所有写入操作,网络恢复后自动同步,重启应用也不会丢失缓存的操作:

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        // 全局只需要调用一次
        FirebaseDatabase.getInstance().setPersistenceEnabled(true)
    }
}

注意:Firebase默认离线缓存上限为10MB,若考勤数据量较大可结合本地SQLite做双重保障

2. 本地SQLite新增待同步队列表

在现有SQLite数据库中新增pending_attendance表,用于存储未上传的考勤数据,字段参考:

  • 主键id
  • 考勤数据JSON串
  • 同步状态(0=待同步、1=已同步)
  • 记录创建时间戳

每次用户提交考勤时,先将数据写入该表标记为待同步,再调用Firebase写入接口,本地写入成功即可给用户返回操作成功提示,无需等待网络返回。

3. 触发同步的两个时机

应用启动时主动同步

每次应用冷启动完成后,主动遍历本地所有待同步的考勤记录,按时间顺序依次上传到Firebase,上传成功后更新本地记录状态为已同步或直接删除记录。

网络恢复时自动同步

注册系统网络状态回调,监听到网络从断开变为连接状态时,立即触发一次同步操作,代码示例:

val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        // 网络恢复,触发同步
        syncPendingAttendance()
    }
}
// 注册回调
connectivityManager.registerDefaultNetworkCallback(networkCallback)

4. 同步逻辑实现示例

// 同步待上传考勤数据
private fun syncPendingAttendance() {
    val db = dbHelper.readableDatabase
    // 查询所有待同步记录,按创建时间升序保证顺序上传
    val cursor = db.query(
        "pending_attendance",
        null,
        "sync_status = ?",
        arrayOf("0"),
        null, null,
        "create_time ASC"
    )
    
    val pendingList = mutableListOf<PendingAttendance>()
    with(cursor) {
        while (moveToNext()) {
            val id = getLong(getColumnIndexOrThrow("id"))
            val json = getString(getColumnIndexOrThrow("attendance_json"))
            pendingList.add(PendingAttendance(id, json))
        }
        close()
    }
    
    val attendanceRef = FirebaseDatabase.getInstance().getReference("attendance")
    pendingList.forEach { record ->
        val attendanceData = Gson().fromJson(record.json, Attendance::class.java)
        attendanceRef.child(attendanceData.recordId).setValue(attendanceData)
            .addOnSuccessListener {
                // 上传成功,删除本地待同步记录
                db.delete("pending_attendance", "id = ?", arrayOf(record.id.toString()))
            }
    }
}

内容的提问来源于stack exchange,提问作者Brijesh Chauhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:54:05