-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moved Firestore internals to different package
- Loading branch information
Showing
43 changed files
with
1,720 additions
and
1,295 deletions.
There are no files selected for viewing
405 changes: 1 addition & 404 deletions
405
firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt
Large diffs are not rendered by default.
Oops, something went wrong.
25 changes: 25 additions & 0 deletions
25
...idMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeCollectionReferenceWrapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package dev.gitlive.firebase.firestore.internal | ||
|
||
import dev.gitlive.firebase.firestore.NativeCollectionReference | ||
import dev.gitlive.firebase.internal.EncodedObject | ||
import dev.gitlive.firebase.internal.android | ||
import kotlinx.coroutines.tasks.await | ||
|
||
@PublishedApi | ||
internal actual class NativeCollectionReferenceWrapper internal actual constructor(actual override val native: NativeCollectionReference) : NativeQueryWrapper(native) { | ||
|
||
actual val path: String | ||
get() = native.path | ||
|
||
actual val document: NativeDocumentReference | ||
get() = NativeDocumentReference(native.document()) | ||
|
||
actual val parent: NativeDocumentReference? | ||
get() = native.parent?.let{ NativeDocumentReference(it) } | ||
|
||
actual fun document(documentPath: String) = | ||
NativeDocumentReference(native.document(documentPath)) | ||
|
||
actual suspend fun addEncoded(data: EncodedObject) = | ||
NativeDocumentReference(native.add(data.android).await()) | ||
} |
88 changes: 88 additions & 0 deletions
88
...src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package dev.gitlive.firebase.firestore.internal | ||
|
||
import com.google.android.gms.tasks.TaskExecutors | ||
import com.google.firebase.firestore.MetadataChanges | ||
import dev.gitlive.firebase.firestore.EncodedFieldPath | ||
import dev.gitlive.firebase.firestore.NativeDocumentReferenceType | ||
import dev.gitlive.firebase.firestore.NativeDocumentSnapshot | ||
import dev.gitlive.firebase.firestore.Source | ||
import dev.gitlive.firebase.firestore.performUpdate | ||
import dev.gitlive.firebase.internal.EncodedObject | ||
import dev.gitlive.firebase.internal.android | ||
import kotlinx.coroutines.channels.ProducerScope | ||
import kotlinx.coroutines.channels.awaitClose | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.callbackFlow | ||
import kotlinx.coroutines.tasks.await | ||
|
||
@PublishedApi | ||
internal actual class NativeDocumentReference actual constructor(actual val nativeValue: NativeDocumentReferenceType) { | ||
val android: NativeDocumentReferenceType by ::nativeValue | ||
actual val id: String | ||
get() = android.id | ||
|
||
actual val path: String | ||
get() = android.path | ||
|
||
actual val parent: NativeCollectionReferenceWrapper | ||
get() = NativeCollectionReferenceWrapper(android.parent) | ||
|
||
actual fun collection(collectionPath: String) = android.collection(collectionPath) | ||
|
||
actual suspend fun get(source: Source) = | ||
android.get(source.toAndroidSource()).await() | ||
|
||
actual suspend fun setEncoded(encodedData: EncodedObject, setOptions: SetOptions) { | ||
val task = (setOptions.android?.let { | ||
android.set(encodedData.android, it) | ||
} ?: android.set(encodedData.android)) | ||
task.await() | ||
} | ||
|
||
actual suspend fun updateEncoded(encodedData: EncodedObject) { | ||
android.update(encodedData.android).await() | ||
} | ||
|
||
actual suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List<Pair<String, Any?>>) { | ||
encodedFieldsAndValues.takeUnless { encodedFieldsAndValues.isEmpty() }?.let { | ||
android.update(encodedFieldsAndValues.toMap()) | ||
}?.await() | ||
} | ||
|
||
actual suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List<Pair<EncodedFieldPath, Any?>>) { | ||
encodedFieldsAndValues.takeUnless { encodedFieldsAndValues.isEmpty() } | ||
?.performUpdate { field, value, moreFieldsAndValues -> | ||
android.update(field, value, *moreFieldsAndValues) | ||
}?.await() | ||
} | ||
|
||
actual suspend fun delete() { | ||
android.delete().await() | ||
} | ||
|
||
actual val snapshots: Flow<NativeDocumentSnapshot> get() = snapshots() | ||
|
||
actual fun snapshots(includeMetadataChanges: Boolean) = addSnapshotListener(includeMetadataChanges) { snapshot, exception -> | ||
snapshot?.let { trySend(snapshot) } | ||
exception?.let { close(exception) } | ||
} | ||
|
||
override fun equals(other: Any?): Boolean = | ||
this === other || other is NativeDocumentReference && nativeValue == other.nativeValue | ||
override fun hashCode(): Int = nativeValue.hashCode() | ||
override fun toString(): String = nativeValue.toString() | ||
|
||
private fun addSnapshotListener( | ||
includeMetadataChanges: Boolean = false, | ||
listener: ProducerScope<NativeDocumentSnapshot>.(com.google.firebase.firestore.DocumentSnapshot?, com.google.firebase.firestore.FirebaseFirestoreException?) -> Unit | ||
) = callbackFlow { | ||
val executor = callbackExecutorMap[android.firestore] ?: TaskExecutors.MAIN_THREAD | ||
val metadataChanges = | ||
if (includeMetadataChanges) MetadataChanges.INCLUDE else MetadataChanges.EXCLUDE | ||
val registration = | ||
android.addSnapshotListener(executor, metadataChanges) { snapshots, exception -> | ||
listener(snapshots, exception) | ||
} | ||
awaitClose { registration.remove() } | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
...droidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentSnapshotWrapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package dev.gitlive.firebase.firestore.internal | ||
|
||
import dev.gitlive.firebase.firestore.EncodedFieldPath | ||
import dev.gitlive.firebase.firestore.ServerTimestampBehavior | ||
import dev.gitlive.firebase.firestore.SnapshotMetadata | ||
|
||
@PublishedApi | ||
internal actual class NativeDocumentSnapshotWrapper actual internal constructor(actual val native: com.google.firebase.firestore.DocumentSnapshot) { | ||
|
||
actual val id get() = native.id | ||
actual val reference get() = NativeDocumentReference(native.reference) | ||
|
||
actual fun getEncoded(field: String, serverTimestampBehavior: ServerTimestampBehavior): Any? = native.get(field, serverTimestampBehavior.toAndroid()) | ||
actual fun getEncoded(fieldPath: EncodedFieldPath, serverTimestampBehavior: ServerTimestampBehavior): Any? = native.get(fieldPath, serverTimestampBehavior.toAndroid()) | ||
actual fun encodedData(serverTimestampBehavior: ServerTimestampBehavior): Any? = native.getData(serverTimestampBehavior.toAndroid()) | ||
|
||
actual fun contains(field: String) = native.contains(field) | ||
actual fun contains(fieldPath: EncodedFieldPath) = native.contains(fieldPath) | ||
|
||
actual val exists get() = native.exists() | ||
|
||
actual val metadata: SnapshotMetadata get() = SnapshotMetadata(native.metadata) | ||
|
||
fun ServerTimestampBehavior.toAndroid(): com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior = when (this) { | ||
ServerTimestampBehavior.ESTIMATE -> com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior.ESTIMATE | ||
ServerTimestampBehavior.NONE -> com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior.NONE | ||
ServerTimestampBehavior.PREVIOUS -> com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior.PREVIOUS | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
...roidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeFirebaseFirestoreWrapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package dev.gitlive.firebase.firestore.internal | ||
|
||
import com.google.android.gms.tasks.TaskExecutors | ||
import com.google.firebase.firestore.MemoryCacheSettings | ||
import com.google.firebase.firestore.MemoryEagerGcSettings | ||
import com.google.firebase.firestore.MemoryLruGcSettings | ||
import com.google.firebase.firestore.PersistentCacheSettings | ||
import com.google.firebase.firestore.firestoreSettings | ||
import dev.gitlive.firebase.firestore.FirebaseFirestoreSettings | ||
import dev.gitlive.firebase.firestore.LocalCacheSettings | ||
import dev.gitlive.firebase.firestore.MemoryGarbageCollectorSettings | ||
import dev.gitlive.firebase.firestore.NativeFirebaseFirestore | ||
import dev.gitlive.firebase.firestore.NativeTransaction | ||
import dev.gitlive.firebase.firestore.android | ||
import kotlinx.coroutines.runBlocking | ||
import kotlinx.coroutines.tasks.await | ||
|
||
internal actual class NativeFirebaseFirestoreWrapper actual constructor(actual val native: NativeFirebaseFirestore) { | ||
|
||
actual var settings: FirebaseFirestoreSettings | ||
get() = with(native.firestoreSettings) { | ||
FirebaseFirestoreSettings( | ||
isSslEnabled, | ||
host, | ||
cacheSettings?.let { localCacheSettings -> | ||
when (localCacheSettings) { | ||
is MemoryCacheSettings -> { | ||
val garbageCollectionSettings = | ||
when (val settings = localCacheSettings.garbageCollectorSettings) { | ||
is MemoryEagerGcSettings -> MemoryGarbageCollectorSettings.Eager | ||
is MemoryLruGcSettings -> MemoryGarbageCollectorSettings.LRUGC( | ||
settings.sizeBytes | ||
) | ||
|
||
else -> throw IllegalArgumentException("Existing settings does not have valid GarbageCollectionSettings") | ||
} | ||
LocalCacheSettings.Memory(garbageCollectionSettings) | ||
} | ||
|
||
is PersistentCacheSettings -> LocalCacheSettings.Persistent( | ||
localCacheSettings.sizeBytes | ||
) | ||
|
||
else -> throw IllegalArgumentException("Existing settings is not of a valid type") | ||
} | ||
} ?: kotlin.run { | ||
@Suppress("DEPRECATION") | ||
when { | ||
isPersistenceEnabled -> LocalCacheSettings.Persistent(cacheSizeBytes) | ||
cacheSizeBytes == FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED -> LocalCacheSettings.Memory( | ||
MemoryGarbageCollectorSettings.Eager | ||
) | ||
|
||
else -> LocalCacheSettings.Memory( | ||
MemoryGarbageCollectorSettings.LRUGC( | ||
cacheSizeBytes | ||
) | ||
) | ||
} | ||
}, | ||
callbackExecutorMap[native] ?: TaskExecutors.MAIN_THREAD | ||
) | ||
} | ||
set(value) { | ||
native.firestoreSettings = firestoreSettings { | ||
isSslEnabled = value.sslEnabled | ||
host = value.host | ||
setLocalCacheSettings(value.cacheSettings.android) | ||
} | ||
callbackExecutorMap[native] = value.callbackExecutor | ||
} | ||
|
||
actual fun collection(collectionPath: String) = native.collection(collectionPath) | ||
|
||
actual fun collectionGroup(collectionId: String) = native.collectionGroup(collectionId) | ||
|
||
actual fun document(documentPath: String) = | ||
NativeDocumentReference(native.document(documentPath)) | ||
|
||
actual fun batch() = native.batch() | ||
|
||
actual fun setLoggingEnabled(loggingEnabled: Boolean) = | ||
com.google.firebase.firestore.FirebaseFirestore.setLoggingEnabled(loggingEnabled) | ||
|
||
actual suspend fun <T> runTransaction(func: suspend NativeTransaction.() -> T): T = | ||
native.runTransaction { runBlocking { it.func() } }.await() | ||
|
||
actual suspend fun clearPersistence() = | ||
native.clearPersistence().await().run { } | ||
|
||
actual fun useEmulator(host: String, port: Int) { | ||
native.useEmulator(host, port) | ||
} | ||
|
||
actual suspend fun disableNetwork() = | ||
native.disableNetwork().await().run { } | ||
|
||
actual suspend fun enableNetwork() = | ||
native.enableNetwork().await().run { } | ||
|
||
} |
138 changes: 138 additions & 0 deletions
138
...tore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package dev.gitlive.firebase.firestore.internal | ||
|
||
import com.google.android.gms.tasks.TaskExecutors | ||
import com.google.firebase.firestore.FieldPath | ||
import com.google.firebase.firestore.MetadataChanges | ||
import com.google.firebase.firestore.Query | ||
import dev.gitlive.firebase.firestore.Direction | ||
import dev.gitlive.firebase.firestore.EncodedFieldPath | ||
import dev.gitlive.firebase.firestore.Filter | ||
import dev.gitlive.firebase.firestore.NativeDocumentSnapshot | ||
import dev.gitlive.firebase.firestore.QuerySnapshot | ||
import dev.gitlive.firebase.firestore.Source | ||
import dev.gitlive.firebase.firestore.WhereConstraint | ||
import kotlinx.coroutines.channels.ProducerScope | ||
import kotlinx.coroutines.channels.awaitClose | ||
import kotlinx.coroutines.flow.callbackFlow | ||
import kotlinx.coroutines.tasks.await | ||
|
||
@PublishedApi | ||
internal actual open class NativeQueryWrapper actual internal constructor(actual open val native: Query) { | ||
|
||
actual fun limit(limit: Number) = native.limit(limit.toLong()) | ||
|
||
actual val snapshots get() = callbackFlow<QuerySnapshot> { | ||
val listener = native.addSnapshotListener { snapshot, exception -> | ||
snapshot?.let { trySend(QuerySnapshot(snapshot)) } | ||
exception?.let { close(exception) } | ||
} | ||
awaitClose { listener.remove() } | ||
} | ||
|
||
actual fun snapshots(includeMetadataChanges: Boolean) = callbackFlow<QuerySnapshot> { | ||
val metadataChanges = | ||
if (includeMetadataChanges) MetadataChanges.INCLUDE else MetadataChanges.EXCLUDE | ||
val listener = native.addSnapshotListener(metadataChanges) { snapshot, exception -> | ||
snapshot?.let { trySend(QuerySnapshot(snapshot)) } | ||
exception?.let { close(exception) } | ||
} | ||
awaitClose { listener.remove() } | ||
} | ||
|
||
actual suspend fun get(source: Source): QuerySnapshot = | ||
QuerySnapshot(native.get(source.toAndroidSource()).await()) | ||
|
||
actual fun where(filter: Filter) = native.where(filter.toAndroidFilter()) | ||
|
||
private fun Filter.toAndroidFilter(): com.google.firebase.firestore.Filter = when (this) { | ||
is Filter.And -> com.google.firebase.firestore.Filter.and(*filters.map { it.toAndroidFilter() } | ||
.toTypedArray()) | ||
is Filter.Or -> com.google.firebase.firestore.Filter.or(*filters.map { it.toAndroidFilter() } | ||
.toTypedArray()) | ||
is Filter.Field -> { | ||
when (constraint) { | ||
is WhereConstraint.ForNullableObject -> { | ||
val modifier: (String, Any?) -> com.google.firebase.firestore.Filter = when (constraint) { | ||
is WhereConstraint.EqualTo -> com.google.firebase.firestore.Filter::equalTo | ||
is WhereConstraint.NotEqualTo -> com.google.firebase.firestore.Filter::notEqualTo | ||
} | ||
modifier.invoke(field, constraint.safeValue) | ||
} | ||
is WhereConstraint.ForObject -> { | ||
val modifier: (String, Any) -> com.google.firebase.firestore.Filter = when (constraint) { | ||
is WhereConstraint.LessThan -> com.google.firebase.firestore.Filter::lessThan | ||
is WhereConstraint.GreaterThan -> com.google.firebase.firestore.Filter::greaterThan | ||
is WhereConstraint.LessThanOrEqualTo -> com.google.firebase.firestore.Filter::lessThanOrEqualTo | ||
is WhereConstraint.GreaterThanOrEqualTo -> com.google.firebase.firestore.Filter::greaterThanOrEqualTo | ||
is WhereConstraint.ArrayContains -> com.google.firebase.firestore.Filter::arrayContains | ||
} | ||
modifier.invoke(field, constraint.safeValue) | ||
} | ||
is WhereConstraint.ForArray -> { | ||
val modifier: (String, List<Any>) -> com.google.firebase.firestore.Filter = when (constraint) { | ||
is WhereConstraint.InArray -> com.google.firebase.firestore.Filter::inArray | ||
is WhereConstraint.ArrayContainsAny -> com.google.firebase.firestore.Filter::arrayContainsAny | ||
is WhereConstraint.NotInArray -> com.google.firebase.firestore.Filter::notInArray | ||
} | ||
modifier.invoke(field, constraint.safeValues) | ||
} | ||
} | ||
} | ||
is Filter.Path -> { | ||
when (constraint) { | ||
is WhereConstraint.ForNullableObject -> { | ||
val modifier: (FieldPath, Any?) -> com.google.firebase.firestore.Filter = when (constraint) { | ||
is WhereConstraint.EqualTo -> com.google.firebase.firestore.Filter::equalTo | ||
is WhereConstraint.NotEqualTo -> com.google.firebase.firestore.Filter::notEqualTo | ||
} | ||
modifier.invoke(path.android, constraint.safeValue) | ||
} | ||
is WhereConstraint.ForObject -> { | ||
val modifier: (FieldPath, Any) -> com.google.firebase.firestore.Filter = when (constraint) { | ||
is WhereConstraint.LessThan -> com.google.firebase.firestore.Filter::lessThan | ||
is WhereConstraint.GreaterThan -> com.google.firebase.firestore.Filter::greaterThan | ||
is WhereConstraint.LessThanOrEqualTo -> com.google.firebase.firestore.Filter::lessThanOrEqualTo | ||
is WhereConstraint.GreaterThanOrEqualTo -> com.google.firebase.firestore.Filter::greaterThanOrEqualTo | ||
is WhereConstraint.ArrayContains -> com.google.firebase.firestore.Filter::arrayContains | ||
} | ||
modifier.invoke(path.android, constraint.safeValue) | ||
} | ||
is WhereConstraint.ForArray -> { | ||
val modifier: (FieldPath, List<Any>) -> com.google.firebase.firestore.Filter = when (constraint) { | ||
is WhereConstraint.InArray -> com.google.firebase.firestore.Filter::inArray | ||
is WhereConstraint.ArrayContainsAny -> com.google.firebase.firestore.Filter::arrayContainsAny | ||
is WhereConstraint.NotInArray -> com.google.firebase.firestore.Filter::notInArray | ||
} | ||
modifier.invoke(path.android, constraint.safeValues) | ||
} | ||
} | ||
} | ||
} | ||
|
||
actual fun orderBy(field: String, direction: Direction) = native.orderBy(field, direction) | ||
actual fun orderBy(field: EncodedFieldPath, direction: Direction) = native.orderBy(field, direction) | ||
|
||
actual fun startAfter(document: NativeDocumentSnapshot) = native.startAfter(document) | ||
actual fun startAfter(vararg fieldValues: Any) = native.startAfter(*fieldValues) | ||
actual fun startAt(document: NativeDocumentSnapshot) = native.startAt(document) | ||
actual fun startAt(vararg fieldValues: Any) = native.startAt(*fieldValues) | ||
|
||
actual fun endBefore(document: NativeDocumentSnapshot) = native.endBefore(document) | ||
actual fun endBefore(vararg fieldValues: Any) = native.endBefore(*fieldValues) | ||
actual fun endAt(document: NativeDocumentSnapshot) = native.endAt(document) | ||
actual fun endAt(vararg fieldValues: Any) = native.endAt(*fieldValues) | ||
|
||
private fun addSnapshotListener( | ||
includeMetadataChanges: Boolean = false, | ||
listener: ProducerScope<QuerySnapshot>.(com.google.firebase.firestore.QuerySnapshot?, com.google.firebase.firestore.FirebaseFirestoreException?) -> Unit | ||
) = callbackFlow { | ||
val executor = callbackExecutorMap[native.firestore] ?: TaskExecutors.MAIN_THREAD | ||
val metadataChanges = | ||
if (includeMetadataChanges) MetadataChanges.INCLUDE else MetadataChanges.EXCLUDE | ||
val registration = | ||
native.addSnapshotListener(executor, metadataChanges) { snapshots, exception -> | ||
listener(snapshots, exception) | ||
} | ||
awaitClose { registration.remove() } | ||
} | ||
} |
Oops, something went wrong.