FirebaseDataSource

Interface for Firebase Firestore data source operations.

This interface defines CRUD operations for syncing data between the local Room database and Firebase Firestore. It implements an offline-first sync pattern where:

  • Local Room database is the source of truth for the UI

  • Firestore serves as the remote backup and sync hub

  • Changes are synchronized bidirectionally between local and remote

Sync Strategy

Pull (Download from Firestore):

  • Query items where lastUpdated > lastSyncTimestamp

  • Merge remote changes into local database

  • Handle conflicts (typically last-write-wins)

Push (Upload to Firestore):

  • Query local items with pending sync actions (CREATE, UPDATE, DELETE)

  • Upload changes to Firestore

  • Mark items as synced after successful upload

Firestore Structure

/dev.atick.jetpack/
/jetpacks/
/{userId}/
/{jetpackId}/
- id: String
- name: String
- price: Double
- userId: String
- lastUpdated: Long
- lastSynced: Long
- deleted: Boolean

Usage in Repository

class HomeRepository @Inject constructor(
private val localDataSource: LocalDataSource,
private val firebaseDataSource: FirebaseDataSource,
private val authDataSource: AuthDataSource
) {
// Pull remote changes
suspend fun pullData(): Result<Unit> = suspendRunCatching {
val userId = authDataSource.getCurrentUser()?.id ?: return@suspendRunCatching
val lastSync = localDataSource.getLastSyncTimestamp()
val remoteItems = firebaseDataSource.pullJetpacks(userId, lastSync)

// Merge into local database
remoteItems.forEach { remote ->
localDataSource.upsertJetpack(remote.toEntity())
}
}

// Push local changes
suspend fun pushData(): Result<Unit> = suspendRunCatching {
val pendingItems = localDataSource.getPendingSyncItems()

pendingItems.forEach { local ->
when (local.syncAction) {
SyncAction.CREATE, SyncAction.UPDATE ->
firebaseDataSource.createOrUpdateJetpack(local.toFirebase())
SyncAction.DELETE ->
firebaseDataSource.deleteJetpack(local.toFirebase())
SyncAction.SYNCED -> { /* Skip */}
}
localDataSource.markAsSynced(local.id)
}
}
}

Thread Safety

All operations are suspend functions and should be called from appropriate coroutine contexts. The implementation uses Firebase's built-in thread handling which is safe for concurrent access.

Error Handling

Operations can throw:

  • FirebaseFirestoreException - Firestore-specific errors

  • FirebaseNetworkException - Network connectivity issues

  • SecurityException - Firestore security rules violations

See also

dev.atick.core.room.data.LocalDataSource

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
abstract suspend fun createJetpack(firebaseJetpack: FirebaseJetpack)

Creates a new Jetpack item in Firestore.

Link copied to clipboard
abstract suspend fun createOrUpdateJetpack(firebaseJetpack: FirebaseJetpack)

Creates or updates a Jetpack item in Firestore (upsert operation).

Link copied to clipboard
abstract suspend fun deleteJetpack(firebaseJetpack: FirebaseJetpack)

Deletes a Jetpack item from Firestore (hard delete).

Link copied to clipboard
abstract suspend fun pullJetpacks(userId: String, lastSynced: Long): List<FirebaseJetpack>

Pulls (downloads) a list of Jetpack items that have been updated since the last sync.