无网络时如何保存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
相关产品推荐
相关产品推荐

