From 377b887d29f0a0e9372645283d6ffe0d49a016da Mon Sep 17 00:00:00 2001 From: David Holas Date: Thu, 27 Jun 2024 06:45:59 +0200 Subject: [PATCH 01/33] Missing fields added to AuthResult Adds missing fields to AuthResult and makes its constructor public --- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 21 ++++++++++++- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 9 ++++++ .../kotlin/dev/gitlive/firebase/auth/auth.kt | 31 ++++++++++++++++++- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 22 ++++++++++++- .../gitlive/firebase/auth/externals/auth.kt | 8 +++++ .../kotlin/dev/gitlive/firebase/auth/auth.kt | 19 +++++++++++- 6 files changed, 106 insertions(+), 4 deletions(-) diff --git a/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 1ea49e666..f4ecc0d8a 100644 --- a/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -110,9 +110,28 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase. actual fun useEmulator(host: String, port: Int) = android.useEmulator(host, port) } -actual class AuthResult internal constructor(val android: com.google.firebase.auth.AuthResult) { +actual class AuthResult( + val android: com.google.firebase.auth.AuthResult, +) { actual val user: FirebaseUser? get() = android.user?.let { FirebaseUser(it) } + actual val credential: AuthCredential? + get() = android.credential?.let { AuthCredential(it) } + actual val additionalUserInfo: AdditionalUserInfo? + get() = android.additionalUserInfo?.let { AdditionalUserInfo(it) } +} + +actual class AdditionalUserInfo( + val android: com.google.firebase.auth.AdditionalUserInfo, +) { + actual val providerId: String? + get() = android.providerId + actual val username: String? + get() = android.username + actual val profile: Map? + get() = android.profile + actual val isNewUser: Boolean + get() = android.isNewUser } actual class AuthTokenResult(val android: com.google.firebase.auth.GetTokenResult) { diff --git a/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 8f6eb0c01..b0c045a2c 100644 --- a/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -41,6 +41,15 @@ expect class FirebaseAuth { expect class AuthResult { val user: FirebaseUser? + val credential: AuthCredential? + val additionalUserInfo: AdditionalUserInfo? +} + +expect class AdditionalUserInfo { + val providerId: String? + val username: String? + val profile: Map? + val isNewUser: Boolean } expect class AuthTokenResult { diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 486deaefa..def7f1a5b 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -15,7 +15,9 @@ import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import platform.Foundation.NSError +import platform.Foundation.NSString import platform.Foundation.NSURL +import kotlin.coroutines.suspendCoroutine actual val Firebase.auth @@ -101,9 +103,36 @@ actual class FirebaseAuth internal constructor(val ios: FIRAuth) { actual fun useEmulator(host: String, port: Int) = ios.useEmulatorWithHost(host, port.toLong()) } -actual class AuthResult internal constructor(val ios: FIRAuthDataResult) { +actual class AuthResult( + val ios: FIRAuthDataResult, +) { actual val user: FirebaseUser? get() = FirebaseUser(ios.user) + actual val credential: AuthCredential? + get() = ios.credential?.let { AuthCredential(it) } + actual val additionalUserInfo: AdditionalUserInfo? + get() = ios.additionalUserInfo?.let { AdditionalUserInfo(it) } +} + +actual class AdditionalUserInfo( + val ios: FIRAdditionalUserInfo, +) { + actual val providerId: String? + get() = ios.providerID + actual val username: String? + get() = ios.username + actual val profile: Map? + get() = ios.profile + ?.mapNotNull { (key, value) -> + if (key is NSString && value != null) { + key.toString() to value + } else { + null + } + } + ?.toMap() + actual val isNewUser: Boolean + get() = ios.newUser } actual class AuthTokenResult(val ios: FIRAuthTokenResult) { diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt index f2db371b4..b50486df0 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import kotlin.js.json import dev.gitlive.firebase.auth.externals.AuthResult as JsAuthResult +import dev.gitlive.firebase.auth.externals.AdditionalUserInfo as JsAdditionalUserInfo actual val Firebase.auth get() = rethrow { FirebaseAuth(getAuth()) } @@ -106,9 +107,28 @@ actual class FirebaseAuth internal constructor(val js: Auth) { actual fun useEmulator(host: String, port: Int) = rethrow { connectAuthEmulator(js, "http://$host:$port") } } -actual class AuthResult internal constructor(val js: JsAuthResult) { +actual class AuthResult( + val js: JsAuthResult, +) { actual val user: FirebaseUser? get() = rethrow { js.user?.let { FirebaseUser(it) } } + actual val credential: AuthCredential? + get() = rethrow { js.credential?.let { AuthCredential(it) } } + actual val additionalUserInfo: AdditionalUserInfo? + get() = js.additionalUserInfo?.let { AdditionalUserInfo(it) } +} + +actual class AdditionalUserInfo( + val js: JsAdditionalUserInfo, +) { + actual val providerId: String? + get() = js.providerId + actual val username: String? + get() = js.username + actual val profile: Map? + get() = js.profile + actual val isNewUser: Boolean + get() = js.newUser } actual class AuthTokenResult(val js: IdTokenResult) { diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt index e3bf651d9..3658511f7 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt @@ -170,6 +170,14 @@ external interface AuthResult { val credential: AuthCredential? val operationType: String? val user: User? + val additionalUserInfo: AdditionalUserInfo? +} + +external interface AdditionalUserInfo { + val providerId: String? + val username: String? + val profile: Map? + val newUser: Boolean } external interface AuthCredential { diff --git a/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 839a4b2a4..50fdb9c08 100644 --- a/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -110,9 +110,26 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase. actual fun useEmulator(host: String, port: Int) = android.useEmulator(host, port) } -actual class AuthResult internal constructor(val android: com.google.firebase.auth.AuthResult) { +actual class AuthResult( + val android: com.google.firebase.auth.AuthResult, +) { actual val user: FirebaseUser? get() = android.user?.let { FirebaseUser(it) } + actual val credential: AuthCredential? + get() { throw NotImplementedError() } + actual val additionalUserInfo: AdditionalUserInfo? + get() { throw NotImplementedError() } +} + +actual class AdditionalUserInfo { + actual val providerId: String? + get() { throw NotImplementedError() } + actual val username: String? + get() { throw NotImplementedError() } + actual val profile: Map? + get() { throw NotImplementedError() } + actual val isNewUser: Boolean + get() { throw NotImplementedError() } } actual class AuthTokenResult(val android: com.google.firebase.auth.GetTokenResult) { From 31d8466dc8276f21a97634beb620771799484bfe Mon Sep 17 00:00:00 2001 From: David Holas Date: Sun, 30 Jun 2024 19:09:56 +0200 Subject: [PATCH 02/33] Removed unused import --- .../src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 46540e4e4..45bc6f07f 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -18,7 +18,6 @@ import kotlinx.coroutines.flow.Flow import platform.Foundation.NSError import platform.Foundation.NSString import platform.Foundation.NSURL -import kotlin.coroutines.suspendCoroutine public actual val Firebase.auth: FirebaseAuth get() = FirebaseAuth(FIRAuth.auth()) From 37867cff96c7cbb9e3bede4074b173c49587d0ff Mon Sep 17 00:00:00 2001 From: David Holas Date: Sun, 30 Jun 2024 19:23:21 +0200 Subject: [PATCH 03/33] AuthResult test --- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index 9dcf36903..25ffb21b4 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -127,6 +127,21 @@ class FirebaseAuthTest { assertEquals("password", credential.providerId) } + @Test + fun testAuthResultStructure() = runTest { + val uid = getTestUid("test@test.com", "test123") + val result = auth.signInWithEmailAndPassword("test@test.com", "test123") + assertNotNull(result.user) + assertEquals(uid, result.user!!.uid) + assertNotNull(result.credential) + assertNotNull(result.credential!!.providerId) + assertNotNull(result.additionalUserInfo) + assertNotNull(result.additionalUserInfo!!.providerId) + assertNotNull(result.additionalUserInfo!!.username) + assertNotNull(result.additionalUserInfo!!.profile) + assertNotNull(result.additionalUserInfo!!.isNewUser) + } + private suspend fun getTestUid(email: String, password: String): String { val uid = auth.let { val user = try { From 93b9ddae20f8b27db260cf2bc48ff3c6ade8648b Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 10:01:23 +0200 Subject: [PATCH 04/33] Added messages to asserts in AuthResult test --- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index 25ffb21b4..3af7e01d4 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -131,15 +131,15 @@ class FirebaseAuthTest { fun testAuthResultStructure() = runTest { val uid = getTestUid("test@test.com", "test123") val result = auth.signInWithEmailAndPassword("test@test.com", "test123") - assertNotNull(result.user) - assertEquals(uid, result.user!!.uid) - assertNotNull(result.credential) - assertNotNull(result.credential!!.providerId) - assertNotNull(result.additionalUserInfo) - assertNotNull(result.additionalUserInfo!!.providerId) - assertNotNull(result.additionalUserInfo!!.username) - assertNotNull(result.additionalUserInfo!!.profile) - assertNotNull(result.additionalUserInfo!!.isNewUser) + assertNotNull(result.user, "User does not exist.") + assertEquals(uid, result.user!!.uid, "uid does not match.") + assertNotNull(result.credential, "Credential does not exist.") + assertNotNull(result.credential!!.providerId, "Credential providerId does not exist.") + assertNotNull(result.additionalUserInfo, "AdditionalUserInfo does not exist.") + assertNotNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId does not exist.") + assertNotNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username does not exist.") + assertNotNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile does not exist.") + assertNotNull(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser does not exist.") } private suspend fun getTestUid(email: String, password: String): String { From ef5e5d95d1c6c143a88c379edaf9505d5e358b93 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 10:03:48 +0200 Subject: [PATCH 05/33] JVM lint issues fixed --- .../src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt index e0e0dde41..200f7eee0 100644 --- a/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -17,10 +17,10 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.tasks.await -public actual val Firebase.auth +public actual val Firebase.auth: FirebaseAuth get() = FirebaseAuth(com.google.firebase.auth.FirebaseAuth.getInstance()) -public actual fun Firebase.auth(app: FirebaseApp) = +public actual fun Firebase.auth(app: FirebaseApp): FirebaseAuth = FirebaseAuth(com.google.firebase.auth.FirebaseAuth.getInstance(app.android)) public actual class FirebaseAuth internal constructor(public val android: com.google.firebase.auth.FirebaseAuth) { From be998c3fc33f6589233a2608c5d45a93b4cdaca7 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 11:53:48 +0200 Subject: [PATCH 06/33] JVM lint issues properly fixed --- .../jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 200f7eee0..99c6c73a9 100644 --- a/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jvmMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -129,20 +129,20 @@ public actual class AuthResult( public actual val user: FirebaseUser? get() = android.user?.let { FirebaseUser(it) } public actual val credential: AuthCredential? - get() { throw NotImplementedError() } + get() = throw NotImplementedError() public actual val additionalUserInfo: AdditionalUserInfo? - get() { throw NotImplementedError() } + get() = throw NotImplementedError() } public actual class AdditionalUserInfo { public actual val providerId: String? - get() { throw NotImplementedError() } + get() = throw NotImplementedError() public actual val username: String? - get() { throw NotImplementedError() } + get() = throw NotImplementedError() public actual val profile: Map? - get() { throw NotImplementedError() } + get() = throw NotImplementedError() public actual val isNewUser: Boolean - get() { throw NotImplementedError() } + get() = throw NotImplementedError() } public actual class AuthTokenResult(public val android: com.google.firebase.auth.GetTokenResult) { From f2c2c510861dd63022ed48fca3cc0686b8a202a2 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 12:11:13 +0200 Subject: [PATCH 07/33] Public api updated --- firebase-auth/api/android/firebase-auth.api | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/firebase-auth/api/android/firebase-auth.api b/firebase-auth/api/android/firebase-auth.api index cc211e626..a756fc5bb 100644 --- a/firebase-auth/api/android/firebase-auth.api +++ b/firebase-auth/api/android/firebase-auth.api @@ -73,11 +73,23 @@ public class dev/gitlive/firebase/auth/AuthCredential { public final fun getProviderId ()Ljava/lang/String; } -public final class dev/gitlive/firebase/auth/AuthResult { - public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; - public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; +public final class dev/gitlive/firebase/auth/AdditionalUserInfo { + public fun (Lcom/google/firebase/auth/AdditionalUserInfo;)V + public final fun getAndroid ()Lcom/google/firebase/auth/AdditionalUserInfo; + public final fun getProfile ()Ljava/util/Map; + public final fun getProviderId ()Ljava/lang/String; + public final fun getUsername ()Ljava/lang/String; + public final fun isNewUser ()Z } +public final class dev/gitlive/firebase/auth/AuthResult { + public fun (Lcom/google/firebase/auth/AuthResult;)V + public final fun getAdditionalUserInfo ()Ldev/gitlive/firebase/auth/AdditionalUserInfo; + public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; + public final fun getCredential ()Ldev/gitlive/firebase/auth/AuthCredential; + public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; + } + public final class dev/gitlive/firebase/auth/AuthTokenResult { public fun (Lcom/google/firebase/auth/GetTokenResult;)V public final fun getAndroid ()Lcom/google/firebase/auth/GetTokenResult; From ed24041331992f9a9f03aaf6f870cca5ee5ce793 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 12:31:49 +0200 Subject: [PATCH 08/33] Public api fix --- firebase-auth/api/android/firebase-auth.api | 30 ++++++++++----------- firebase-auth/api/jvm/firebase-auth.api | 11 ++++++++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/firebase-auth/api/android/firebase-auth.api b/firebase-auth/api/android/firebase-auth.api index a756fc5bb..1e1e49450 100644 --- a/firebase-auth/api/android/firebase-auth.api +++ b/firebase-auth/api/android/firebase-auth.api @@ -51,6 +51,15 @@ public final class dev/gitlive/firebase/auth/ActionCodeSettings { public fun toString ()Ljava/lang/String; } +public final class dev/gitlive/firebase/auth/AdditionalUserInfo { + public fun (Lcom/google/firebase/auth/AdditionalUserInfo;)V + public final fun getAndroid ()Lcom/google/firebase/auth/AdditionalUserInfo; + public final fun getProfile ()Ljava/util/Map; + public final fun getProviderId ()Ljava/lang/String; + public final fun getUsername ()Ljava/lang/String; + public final fun isNewUser ()Z +} + public final class dev/gitlive/firebase/auth/AndroidPackageName { public fun (Ljava/lang/String;ZLjava/lang/String;)V public synthetic fun (Ljava/lang/String;ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -73,22 +82,13 @@ public class dev/gitlive/firebase/auth/AuthCredential { public final fun getProviderId ()Ljava/lang/String; } -public final class dev/gitlive/firebase/auth/AdditionalUserInfo { - public fun (Lcom/google/firebase/auth/AdditionalUserInfo;)V - public final fun getAndroid ()Lcom/google/firebase/auth/AdditionalUserInfo; - public final fun getProfile ()Ljava/util/Map; - public final fun getProviderId ()Ljava/lang/String; - public final fun getUsername ()Ljava/lang/String; - public final fun isNewUser ()Z -} - public final class dev/gitlive/firebase/auth/AuthResult { - public fun (Lcom/google/firebase/auth/AuthResult;)V - public final fun getAdditionalUserInfo ()Ldev/gitlive/firebase/auth/AdditionalUserInfo; - public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; - public final fun getCredential ()Ldev/gitlive/firebase/auth/AuthCredential; - public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; - } + public fun (Lcom/google/firebase/auth/AuthResult;)V + public final fun getAdditionalUserInfo ()Ldev/gitlive/firebase/auth/AdditionalUserInfo; + public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; + public final fun getCredential ()Ldev/gitlive/firebase/auth/AuthCredential; + public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; +} public final class dev/gitlive/firebase/auth/AuthTokenResult { public fun (Lcom/google/firebase/auth/GetTokenResult;)V diff --git a/firebase-auth/api/jvm/firebase-auth.api b/firebase-auth/api/jvm/firebase-auth.api index 3afffeac4..b6a0eda07 100644 --- a/firebase-auth/api/jvm/firebase-auth.api +++ b/firebase-auth/api/jvm/firebase-auth.api @@ -51,6 +51,14 @@ public final class dev/gitlive/firebase/auth/ActionCodeSettings { public fun toString ()Ljava/lang/String; } +public final class dev/gitlive/firebase/auth/AdditionalUserInfo { + public fun ()V + public final fun getProfile ()Ljava/util/Map; + public final fun getProviderId ()Ljava/lang/String; + public final fun getUsername ()Ljava/lang/String; + public final fun isNewUser ()Z +} + public final class dev/gitlive/firebase/auth/AndroidPackageName { public fun (Ljava/lang/String;ZLjava/lang/String;)V public synthetic fun (Ljava/lang/String;ZLjava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -74,7 +82,10 @@ public class dev/gitlive/firebase/auth/AuthCredential { } public final class dev/gitlive/firebase/auth/AuthResult { + public fun (Lcom/google/firebase/auth/AuthResult;)V + public final fun getAdditionalUserInfo ()Ldev/gitlive/firebase/auth/AdditionalUserInfo; public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; + public final fun getCredential ()Ldev/gitlive/firebase/auth/AuthCredential; public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; } From 434abaac21d3243052050a04a9b8499e0e76a1b7 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 12:38:20 +0200 Subject: [PATCH 09/33] AuthResult structure test allows null values --- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index 3af7e01d4..8b87c13e9 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -133,13 +133,13 @@ class FirebaseAuthTest { val result = auth.signInWithEmailAndPassword("test@test.com", "test123") assertNotNull(result.user, "User does not exist.") assertEquals(uid, result.user!!.uid, "uid does not match.") - assertNotNull(result.credential, "Credential does not exist.") - assertNotNull(result.credential!!.providerId, "Credential providerId does not exist.") - assertNotNull(result.additionalUserInfo, "AdditionalUserInfo does not exist.") - assertNotNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId does not exist.") - assertNotNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username does not exist.") - assertNotNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile does not exist.") - assertNotNull(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser does not exist.") + assertNull(result.credential, "Credential throws.") + assertNull(result.credential!!.providerId, "Credential providerId throws.") + assertNull(result.additionalUserInfo, "AdditionalUserInfo throws.") + assertNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId throws.") + assertNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username throws.") + assertNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile throws.") + assertNull(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser throws.") } private suspend fun getTestUid(email: String, password: String): String { From 84cdf2c7f240ce5b99b9f4438bf3796a0a309b7c Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 14:54:49 +0200 Subject: [PATCH 10/33] AuthResult structure test unwrap fixed Tests for null using optional unwrap don't make much sense --- .../src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index 8b87c13e9..a2202909f 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -134,12 +134,7 @@ class FirebaseAuthTest { assertNotNull(result.user, "User does not exist.") assertEquals(uid, result.user!!.uid, "uid does not match.") assertNull(result.credential, "Credential throws.") - assertNull(result.credential!!.providerId, "Credential providerId throws.") assertNull(result.additionalUserInfo, "AdditionalUserInfo throws.") - assertNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId throws.") - assertNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username throws.") - assertNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile throws.") - assertNull(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser throws.") } private suspend fun getTestUid(email: String, password: String): String { From a18e3f2b5515070a5914eb4b275b0fa45d755906 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 15:41:08 +0200 Subject: [PATCH 11/33] AuthResult structure additionalUserInfo exists --- .../src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index a2202909f..d197c9bba 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -134,7 +134,11 @@ class FirebaseAuthTest { assertNotNull(result.user, "User does not exist.") assertEquals(uid, result.user!!.uid, "uid does not match.") assertNull(result.credential, "Credential throws.") - assertNull(result.additionalUserInfo, "AdditionalUserInfo throws.") + assertNotNull(result.additionalUserInfo, "AdditionalUserInfo does not exist.") + assertNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId throws.") + assertNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username throws.") + assertNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile throws.") + assertNull(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser throws.") } private suspend fun getTestUid(email: String, password: String): String { From 79a75167bc4b8e2115998edfd75f16c0941e3c56 Mon Sep 17 00:00:00 2001 From: David Holas Date: Mon, 15 Jul 2024 15:53:00 +0200 Subject: [PATCH 12/33] AuthResult structure isNewUser default respected --- .../src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index d197c9bba..56be08491 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -138,7 +138,7 @@ class FirebaseAuthTest { assertNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId throws.") assertNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username throws.") assertNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile throws.") - assertNull(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser throws.") + assertFalse(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser does not exist.") } private suspend fun getTestUid(email: String, password: String): String { From ac4cffaa88f5bae23da4447116dca82017db28aa Mon Sep 17 00:00:00 2001 From: David Holas Date: Wed, 17 Jul 2024 08:11:28 +0200 Subject: [PATCH 13/33] AuthResult structure test made more forgiving Exact values differ on different platforms --- .../commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index 56be08491..33e2a9c21 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -135,10 +135,11 @@ class FirebaseAuthTest { assertEquals(uid, result.user!!.uid, "uid does not match.") assertNull(result.credential, "Credential throws.") assertNotNull(result.additionalUserInfo, "AdditionalUserInfo does not exist.") - assertNull(result.additionalUserInfo!!.providerId, "AdditionalUserInfo providerId throws.") - assertNull(result.additionalUserInfo!!.username, "AdditionalUserInfo username throws.") - assertNull(result.additionalUserInfo!!.profile, "AdditionalUserInfo profile throws.") - assertFalse(result.additionalUserInfo!!.isNewUser, "AdditionalUserInfo isNewUser does not exist.") + // Just test if it does not throw + result.additionalUserInfo!!.providerId + result.additionalUserInfo!!.username + result.additionalUserInfo!!.profile + result.additionalUserInfo!!.isNewUser } private suspend fun getTestUid(email: String, password: String): String { From e5af67d296f55f0e11d40a3ac1c90ae60ab31d0c Mon Sep 17 00:00:00 2001 From: David Holas Date: Wed, 28 Aug 2024 14:16:07 +0200 Subject: [PATCH 14/33] AuthResult map parsing fixed in JS --- .../jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 10 ++++++++-- .../kotlin/dev/gitlive/firebase/auth/externals/auth.kt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 34f5eb20a..61b461adc 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -118,7 +118,7 @@ public actual class AuthResult( public actual val credential: AuthCredential? get() = rethrow { js.credential?.let { AuthCredential(it) } } public actual val additionalUserInfo: AdditionalUserInfo? - get() = js.additionalUserInfo?.let { AdditionalUserInfo(it) } + get() = rethrow { js.additionalUserInfo?.let { AdditionalUserInfo(it) } } } public actual class AdditionalUserInfo( @@ -129,7 +129,13 @@ public actual class AdditionalUserInfo( public actual val username: String? get() = js.username public actual val profile: Map? - get() = js.profile + get() = rethrow { + val profile = js.profile ?: return@rethrow null + val entries = js("Object.entries") as (dynamic) -> Array> + return@rethrow entries + .invoke(profile) + .associate { entry -> entry[0] as String to entry[1] } + } public actual val isNewUser: Boolean get() = js.newUser } diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt index e0136a81e..9b60a95b9 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt @@ -176,7 +176,7 @@ public external interface AuthResult { public external interface AdditionalUserInfo { public val providerId: String? public val username: String? - public val profile: Map? + public val profile: dynamic public val newUser: Boolean } From 9681cf433aff387c35782769ec87aeb5b6653626 Mon Sep 17 00:00:00 2001 From: David Holas Date: Wed, 28 Aug 2024 14:30:08 +0200 Subject: [PATCH 15/33] Used Json? instead od dynamic for better clarity --- .../src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 3 ++- .../jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 61b461adc..07c833c77 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.await import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow +import kotlin.js.Json import kotlin.js.json import dev.gitlive.firebase.auth.externals.AuthResult as JsAuthResult import dev.gitlive.firebase.auth.externals.AdditionalUserInfo as JsAdditionalUserInfo @@ -131,7 +132,7 @@ public actual class AdditionalUserInfo( public actual val profile: Map? get() = rethrow { val profile = js.profile ?: return@rethrow null - val entries = js("Object.entries") as (dynamic) -> Array> + val entries = js("Object.entries") as (Json) -> Array> return@rethrow entries .invoke(profile) .associate { entry -> entry[0] as String to entry[1] } diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt index 9b60a95b9..20c3f14c3 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/externals/auth.kt @@ -176,7 +176,7 @@ public external interface AuthResult { public external interface AdditionalUserInfo { public val providerId: String? public val username: String? - public val profile: dynamic + public val profile: Json? public val newUser: Boolean } From fad36646f05a010d78c3af9370c724d6b94df4f6 Mon Sep 17 00:00:00 2001 From: David Holas Date: Wed, 28 Aug 2024 16:36:02 +0200 Subject: [PATCH 16/33] AuthResult structure JS test fixed --- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt index 33e2a9c21..67a6cffe5 100644 --- a/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -111,6 +111,22 @@ class FirebaseAuthTest { assertEquals(uid, result.user!!.uid) } + @Test + fun testAuthResultStructure() = runTest { + val uid = getTestUid("test@test.com", "test123") + val result = auth.signInWithEmailAndPassword("test@test.com", "test123") + assertNotNull(result.user, "User does not exist.") + assertEquals(uid, result.user!!.uid, "uid does not match.") + assertNull(result.credential, "Credential throws.") + // Just test if it does not throw + result.additionalUserInfo?.let { additionalUserInfo -> + additionalUserInfo.providerId + additionalUserInfo.username + additionalUserInfo.profile + additionalUserInfo.isNewUser + } + } + @Test fun testIsSignInWithEmailLink() { val validLink = "http://localhost:9099/emulator/action?mode=signIn&lang=en&oobCode=_vr0QcFcxcVeLZbrcU-GpTaZiuxlHquqdC8MSy0YM_vzWCTAQgV9Jq&apiKey=fake-api-key&continueUrl=https%3A%2F%2Fexample.com%2Fsignin" @@ -127,21 +143,6 @@ class FirebaseAuthTest { assertEquals("password", credential.providerId) } - @Test - fun testAuthResultStructure() = runTest { - val uid = getTestUid("test@test.com", "test123") - val result = auth.signInWithEmailAndPassword("test@test.com", "test123") - assertNotNull(result.user, "User does not exist.") - assertEquals(uid, result.user!!.uid, "uid does not match.") - assertNull(result.credential, "Credential throws.") - assertNotNull(result.additionalUserInfo, "AdditionalUserInfo does not exist.") - // Just test if it does not throw - result.additionalUserInfo!!.providerId - result.additionalUserInfo!!.username - result.additionalUserInfo!!.profile - result.additionalUserInfo!!.isNewUser - } - private suspend fun getTestUid(email: String, password: String): String { val uid = auth.let { val user = try { From b566e31a6e5a536dbe0e03ae6497b24990ecec0a Mon Sep 17 00:00:00 2001 From: David Holas Date: Thu, 29 Aug 2024 08:10:55 +0200 Subject: [PATCH 17/33] Merge cleanup --- .../src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 887847807..71cca6ed8 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -105,6 +105,7 @@ public actual class FirebaseAuth internal constructor(internal val ios: FIRAuth) public actual fun useEmulator(host: String, port: Int): Unit = ios.useEmulatorWithHost(host, port.toLong()) } + public val AuthResult.ios: FIRAuthDataResult get() = ios public actual class AuthResult(internal val ios: FIRAuthDataResult) { From 1a9a14afced3dd4631e5c166a81652fa8882f934 Mon Sep 17 00:00:00 2001 From: mr-kew Date: Thu, 29 Aug 2024 08:53:43 +0200 Subject: [PATCH 18/33] API dump --- firebase-auth/api/android/firebase-auth.api | 1 - firebase-auth/api/jvm/firebase-auth.api | 1 - 2 files changed, 2 deletions(-) diff --git a/firebase-auth/api/android/firebase-auth.api b/firebase-auth/api/android/firebase-auth.api index ce28ec999..793afeb1f 100644 --- a/firebase-auth/api/android/firebase-auth.api +++ b/firebase-auth/api/android/firebase-auth.api @@ -85,7 +85,6 @@ public class dev/gitlive/firebase/auth/AuthCredential { public final class dev/gitlive/firebase/auth/AuthResult { public fun (Lcom/google/firebase/auth/AuthResult;)V public final fun getAdditionalUserInfo ()Ldev/gitlive/firebase/auth/AdditionalUserInfo; - public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; public final fun getCredential ()Ldev/gitlive/firebase/auth/AuthCredential; public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; } diff --git a/firebase-auth/api/jvm/firebase-auth.api b/firebase-auth/api/jvm/firebase-auth.api index 6b6a51786..f629f1f01 100644 --- a/firebase-auth/api/jvm/firebase-auth.api +++ b/firebase-auth/api/jvm/firebase-auth.api @@ -84,7 +84,6 @@ public class dev/gitlive/firebase/auth/AuthCredential { public final class dev/gitlive/firebase/auth/AuthResult { public fun (Lcom/google/firebase/auth/AuthResult;)V public final fun getAdditionalUserInfo ()Ldev/gitlive/firebase/auth/AdditionalUserInfo; - public final fun getAndroid ()Lcom/google/firebase/auth/AuthResult; public final fun getCredential ()Ldev/gitlive/firebase/auth/AuthCredential; public final fun getUser ()Ldev/gitlive/firebase/auth/FirebaseUser; } From 0428e263f2a3f571d7d6058845c7de7379fd5a4a Mon Sep 17 00:00:00 2001 From: Siarhei Luskanau Date: Fri, 23 Aug 2024 17:48:03 +0200 Subject: [PATCH 19/33] Updated firebase-cocoapods to "11.1.0" --- .../kotlin/dev/gitlive/firebase/auth/auth.kt | 96 ++++++++++--------- .../dev/gitlive/firebase/auth/credentials.kt | 2 +- .../dev/gitlive/firebase/auth/multifactor.kt | 18 ++-- .../kotlin/dev/gitlive/firebase/auth/user.kt | 38 ++++---- .../gitlive/firebase/firestore/Timestamp.kt | 2 +- gradle/libs.versions.toml | 2 +- 6 files changed, 83 insertions(+), 75 deletions(-) diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt index b659b0c68..30cbc9cf0 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -31,7 +31,7 @@ public actual fun Firebase.auth(app: FirebaseApp): FirebaseAuth = FirebaseAuth( public actual class FirebaseAuth internal constructor(internal val ios: FIRAuth) { public actual val currentUser: FirebaseUser? - get() = ios.currentUser?.let { FirebaseUser(it) } + get() = ios.currentUser()?.let { FirebaseUser(it) } public actual val authStateChanged: Flow get() = callbackFlow { val handle = ios.addAuthStateDidChangeListener { _, user -> trySend(user?.let { FirebaseUser(it) }) } @@ -44,7 +44,7 @@ public actual class FirebaseAuth internal constructor(internal val ios: FIRAuth) } public actual var languageCode: String - get() = ios.languageCode ?: "" + get() = ios.languageCode() ?: "" set(value) { ios.setLanguageCode(value) } @@ -90,15 +90,15 @@ public actual class FirebaseAuth internal constructor(internal val ios: FIRAuth) public actual suspend fun checkActionCode(code: String): T { val result: FIRActionCodeInfo = ios.awaitResult { checkActionCode(code, it) } @Suppress("UNCHECKED_CAST") - return when (result.operation) { + return when (result.operation()) { FIRActionCodeOperationEmailLink -> SignInWithEmailLink - FIRActionCodeOperationVerifyEmail -> VerifyEmail(result.email!!) - FIRActionCodeOperationPasswordReset -> PasswordReset(result.email!!) - FIRActionCodeOperationRecoverEmail -> RecoverEmail(result.email!!, result.previousEmail!!) - FIRActionCodeOperationVerifyAndChangeEmail -> VerifyBeforeChangeEmail(result.email!!, result.previousEmail!!) - FIRActionCodeOperationRevertSecondFactorAddition -> RevertSecondFactorAddition(result.email!!, null) - FIRActionCodeOperationUnknown -> throw UnsupportedOperationException(result.operation.toString()) - else -> throw UnsupportedOperationException(result.operation.toString()) + FIRActionCodeOperationVerifyEmail -> VerifyEmail(result.email()) + FIRActionCodeOperationPasswordReset -> PasswordReset(result.email()) + FIRActionCodeOperationRecoverEmail -> RecoverEmail(result.email(), result.previousEmail()!!) + FIRActionCodeOperationVerifyAndChangeEmail -> VerifyBeforeChangeEmail(result.email(), result.previousEmail()!!) + FIRActionCodeOperationRevertSecondFactorAddition -> RevertSecondFactorAddition(result.email(), null) + FIRActionCodeOperationUnknown -> throw UnsupportedOperationException(result.operation().toString()) + else -> throw UnsupportedOperationException(result.operation().toString()) } as T } @@ -108,7 +108,7 @@ public val AuthResult.ios: FIRAuthDataResult get() = ios public actual class AuthResult internal constructor(internal val ios: FIRAuthDataResult) { public actual val user: FirebaseUser? - get() = FirebaseUser(ios.user) + get() = FirebaseUser(ios.user()) } public val AuthTokenResult.ios: FIRAuthTokenResult get() = ios @@ -116,23 +116,23 @@ public actual class AuthTokenResult(internal val ios: FIRAuthTokenResult) { // actual val authTimestamp: Long // get() = ios.authDate public actual val claims: Map - get() = ios.claims.map { it.key.toString() to it.value as Any }.toMap() + get() = ios.claims().map { it.key.toString() to it.value as Any }.toMap() // actual val expirationTimestamp: Long // get() = ios.expirationDate // actual val issuedAtTimestamp: Long // get() = ios.issuedAtDate public actual val signInProvider: String? - get() = ios.signInProvider + get() = ios.signInProvider() public actual val token: String? - get() = ios.token + get() = ios.token() } internal fun ActionCodeSettings.toIos() = FIRActionCodeSettings().also { - it.URL = NSURL.URLWithString(url) + it.setURL(NSURL.URLWithString(url)) androidPackageName?.run { it.setAndroidPackageName(packageName, installIfNotAvailable, minimumVersion) } - it.dynamicLinkDomain = dynamicLinkDomain - it.handleCodeInApp = canHandleCodeInApp + it.setDynamicLinkDomain(dynamicLinkDomain) + it.setHandleCodeInApp(canHandleCodeInApp) iOSBundleId?.run { it.setIOSBundleID(this) } } @@ -184,47 +184,55 @@ internal suspend inline fun T.await(function: T.(callback: (NSError?) -> Uni } private fun NSError.toException() = when (domain) { + // codes from AuthErrors.swift: https://github.com/firebase/firebase-ios-sdk/blob/ + // 2f6ac4c2c61cd57c7ea727009e187b7e1163d613/FirebaseAuth/Sources/Swift/Utilities/ + // AuthErrors.swift#L51 FIRAuthErrorDomain -> when (code) { - FIRAuthErrorCodeInvalidActionCode, - FIRAuthErrorCodeExpiredActionCode, + 17030L, // AuthErrorCode.invalidActionCode + 17029L, // AuthErrorCode.expiredActionCode -> FirebaseAuthActionCodeException(toString()) - FIRAuthErrorCodeInvalidEmail -> FirebaseAuthEmailException(toString()) - - FIRAuthErrorCodeCaptchaCheckFailed, - FIRAuthErrorCodeInvalidPhoneNumber, - FIRAuthErrorCodeMissingPhoneNumber, - FIRAuthErrorCodeInvalidVerificationID, - FIRAuthErrorCodeInvalidVerificationCode, - FIRAuthErrorCodeMissingVerificationID, - FIRAuthErrorCodeMissingVerificationCode, - FIRAuthErrorCodeUserTokenExpired, - FIRAuthErrorCodeInvalidCredential, + 17008L, // AuthErrorCode.invalidEmail + -> FirebaseAuthEmailException(toString()) + + 17056L, // AuthErrorCode.captchaCheckFailed + 17042L, // AuthErrorCode.invalidPhoneNumber + 17041L, // AuthErrorCode.missingPhoneNumber + 17046L, // AuthErrorCode.invalidVerificationID + 17044L, // AuthErrorCode.invalidVerificationCode + 17045L, // AuthErrorCode.missingVerificationID + 17043L, // AuthErrorCode.missingVerificationCode + 17021L, // AuthErrorCode.userTokenExpired + 17004L, // AuthErrorCode.invalidCredential -> FirebaseAuthInvalidCredentialsException(toString()) - FIRAuthErrorCodeWeakPassword -> FirebaseAuthWeakPasswordException(toString()) + 17026L, // AuthErrorCode.weakPassword + -> FirebaseAuthWeakPasswordException(toString()) - FIRAuthErrorCodeInvalidUserToken -> FirebaseAuthInvalidUserException(toString()) + 17017L, // AuthErrorCode.invalidUserToken + -> FirebaseAuthInvalidUserException(toString()) - FIRAuthErrorCodeRequiresRecentLogin -> FirebaseAuthRecentLoginRequiredException(toString()) + 17014L, // AuthErrorCode.requiresRecentLogin + -> FirebaseAuthRecentLoginRequiredException(toString()) - FIRAuthErrorCodeSecondFactorAlreadyEnrolled, - FIRAuthErrorCodeSecondFactorRequired, - FIRAuthErrorCodeMaximumSecondFactorCountExceeded, - FIRAuthErrorCodeMultiFactorInfoNotFound, + 17087L, // AuthErrorCode.secondFactorAlreadyEnrolled + 17078L, // AuthErrorCode.secondFactorRequired + 17088L, // AuthErrorCode.maximumSecondFactorCountExceeded + 17084L, // AuthErrorCode.multiFactorInfoNotFound -> FirebaseAuthMultiFactorException(toString()) - FIRAuthErrorCodeEmailAlreadyInUse, - FIRAuthErrorCodeAccountExistsWithDifferentCredential, - FIRAuthErrorCodeCredentialAlreadyInUse, + 17007L, // AuthErrorCode.emailAlreadyInUse + 17012L, // AuthErrorCode.accountExistsWithDifferentCredential + 17025L, // AuthErrorCode.credentialAlreadyInUse -> FirebaseAuthUserCollisionException(toString()) - FIRAuthErrorCodeWebContextAlreadyPresented, - FIRAuthErrorCodeWebContextCancelled, - FIRAuthErrorCodeWebInternalError, + 17057L, // AuthErrorCode.webContextAlreadyPresented + 17058L, // AuthErrorCode.webContextCancelled + 17062L, // AuthErrorCode.webInternalError -> FirebaseAuthWebException(toString()) - FIRAuthErrorCodeNetworkError -> FirebaseNetworkException(toString()) + 17020L, // AuthErrorCode.networkError + -> FirebaseNetworkException(toString()) else -> FirebaseAuthException(toString()) } diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/credentials.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/credentials.kt index 08387a0e1..5a2084bb9 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/credentials.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/credentials.kt @@ -8,7 +8,7 @@ import cocoapods.FirebaseAuth.* public actual open class AuthCredential(public open val ios: FIRAuthCredential) { public actual val providerId: String - get() = ios.provider + get() = ios.provider() } public actual class PhoneAuthCredential(override val ios: FIRPhoneAuthCredential) : AuthCredential(ios) diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/multifactor.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/multifactor.kt index f389b6abb..3d2c814e5 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/multifactor.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/multifactor.kt @@ -10,7 +10,7 @@ public val MultiFactor.ios: FIRMultiFactor get() = ios public actual class MultiFactor(internal val ios: FIRMultiFactor) { public actual val enrolledFactors: List - get() = ios.enrolledFactors.mapNotNull { info -> (info as? FIRMultiFactorInfo)?.let { MultiFactorInfo(it) } } + get() = ios.enrolledFactors().mapNotNull { info -> (info as? FIRMultiFactorInfo)?.let { MultiFactorInfo(it) } } public actual suspend fun enroll(multiFactorAssertion: MultiFactorAssertion, displayName: String?): Unit = ios.await { enrollWithAssertion(multiFactorAssertion.ios, displayName, it) } public actual suspend fun getSession(): MultiFactorSession = MultiFactorSession(ios.awaitResult { getSessionWithCompletion(completion = it) }) public actual suspend fun unenroll(multiFactorInfo: MultiFactorInfo): Unit = ios.await { unenrollWithInfo(multiFactorInfo.ios, it) } @@ -21,20 +21,20 @@ public val MultiFactorInfo.ios: FIRMultiFactorInfo get() = ios public actual class MultiFactorInfo(internal val ios: FIRMultiFactorInfo) { public actual val displayName: String? - get() = ios.displayName + get() = ios.displayName() public actual val enrollmentTime: Double - get() = ios.enrollmentDate.timeIntervalSinceReferenceDate + get() = ios.enrollmentDate().timeIntervalSinceReferenceDate public actual val factorId: String - get() = ios.factorID + get() = ios.factorID() public actual val uid: String - get() = ios.UID + get() = ios.UID() } public val MultiFactorAssertion.ios: FIRMultiFactorAssertion get() = ios public actual class MultiFactorAssertion(internal val ios: FIRMultiFactorAssertion) { public actual val factorId: String - get() = ios.factorID + get() = ios.factorID() } public val MultiFactorSession.ios: FIRMultiFactorSession get() = ios @@ -44,9 +44,9 @@ public actual class MultiFactorSession(internal val ios: FIRMultiFactorSession) public val MultiFactorResolver.ios: FIRMultiFactorResolver get() = ios public actual class MultiFactorResolver(internal val ios: FIRMultiFactorResolver) { - public actual val auth: FirebaseAuth = FirebaseAuth(ios.auth) - public actual val hints: List = ios.hints.mapNotNull { hint -> (hint as? FIRMultiFactorInfo)?.let { MultiFactorInfo(it) } } - public actual val session: MultiFactorSession = MultiFactorSession(ios.session) + public actual val auth: FirebaseAuth = FirebaseAuth(ios.auth()) + public actual val hints: List = ios.hints().mapNotNull { hint -> (hint as? FIRMultiFactorInfo)?.let { MultiFactorInfo(it) } } + public actual val session: MultiFactorSession = MultiFactorSession(ios.session()) public actual suspend fun resolveSignIn(assertion: MultiFactorAssertion): AuthResult = AuthResult(ios.awaitResult { resolveSignInWithAssertion(assertion.ios, it) }) } diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/user.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/user.kt index f2f6c67cc..d37fc20c0 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/user.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/user.kt @@ -14,27 +14,27 @@ public val FirebaseUser.ios: FIRUser get() = ios public actual class FirebaseUser internal constructor(internal val ios: FIRUser) { public actual val uid: String - get() = ios.uid + get() = ios.uid() public actual val displayName: String? - get() = ios.displayName + get() = ios.displayName() public actual val email: String? - get() = ios.email + get() = ios.email() public actual val phoneNumber: String? - get() = ios.phoneNumber + get() = ios.phoneNumber() public actual val photoURL: String? - get() = ios.photoURL?.absoluteString + get() = ios.photoURL()?.absoluteString public actual val isAnonymous: Boolean - get() = ios.anonymous + get() = ios.anonymous() public actual val isEmailVerified: Boolean - get() = ios.emailVerified + get() = ios.emailVerified() public actual val metaData: UserMetaData? - get() = UserMetaData(ios.metadata) + get() = UserMetaData(ios.metadata()) public actual val multiFactor: MultiFactor - get() = MultiFactor(ios.multiFactor) + get() = MultiFactor(ios.multiFactor()) public actual val providerData: List - get() = ios.providerData.mapNotNull { provider -> (provider as? FIRUserInfoProtocol)?.let { UserInfo(it) } } + get() = ios.providerData().mapNotNull { provider -> (provider as? FIRUserInfoProtocol)?.let { UserInfo(it) } } public actual val providerId: String - get() = ios.providerID + get() = ios.providerID() public actual suspend fun delete(): Unit = ios.await { deleteWithCompletion(it) } @@ -85,24 +85,24 @@ public val UserInfo.ios: FIRUserInfoProtocol get() = ios public actual class UserInfo(internal val ios: FIRUserInfoProtocol) { public actual val displayName: String? - get() = ios.displayName + get() = ios.displayName() public actual val email: String? - get() = ios.email + get() = ios.email() public actual val phoneNumber: String? - get() = ios.phoneNumber + get() = ios.phoneNumber() public actual val photoURL: String? - get() = ios.photoURL?.absoluteString + get() = ios.photoURL()?.absoluteString public actual val providerId: String - get() = ios.providerID + get() = ios.providerID() public actual val uid: String - get() = ios.uid + get() = ios.uid() } public val UserMetaData.ios: FIRUserMetadata get() = ios public actual class UserMetaData(internal val ios: FIRUserMetadata) { public actual val creationTime: Double? - get() = ios.creationDate?.timeIntervalSinceReferenceDate + get() = ios.creationDate()?.timeIntervalSinceReferenceDate public actual val lastSignInTime: Double? - get() = ios.lastSignInDate?.timeIntervalSinceReferenceDate + get() = ios.lastSignInDate()?.timeIntervalSinceReferenceDate } diff --git a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt index d0eb95602..8497833e8 100644 --- a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt +++ b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/Timestamp.kt @@ -1,6 +1,6 @@ package dev.gitlive.firebase.firestore -import cocoapods.FirebaseFirestoreInternal.FIRTimestamp +import cocoapods.FirebaseCore.FIRTimestamp import kotlinx.serialization.Serializable /** A class representing a platform specific Firebase Timestamp. */ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9561276bc..c2a38ad9b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,7 +16,7 @@ kotlinx-datetime = "0.6.1" kotlinter = "4.4.1" settings-api = "2.0" settings-language = "2.0" -firebase-cocoapods = "10.28.0" +firebase-cocoapods = "11.1.0" ios-deploymentTarget = "13.0" test-logger-plugin = "4.0.0" dokka = "1.9.20" From 3eb1a0ce3412685e9bf876fc4db24ccf5199f112 Mon Sep 17 00:00:00 2001 From: mr-kew Date: Thu, 29 Aug 2024 23:40:33 +0200 Subject: [PATCH 20/33] Native properties moved into extensions --- firebase-auth/api/android/firebase-auth.api | 2 +- .../src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 5 ++++- .../src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 4 +++- .../src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 4 +++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/firebase-auth/api/android/firebase-auth.api b/firebase-auth/api/android/firebase-auth.api index 793afeb1f..e6ab3cfef 100644 --- a/firebase-auth/api/android/firebase-auth.api +++ b/firebase-auth/api/android/firebase-auth.api @@ -53,7 +53,6 @@ public final class dev/gitlive/firebase/auth/ActionCodeSettings { public final class dev/gitlive/firebase/auth/AdditionalUserInfo { public fun (Lcom/google/firebase/auth/AdditionalUserInfo;)V - public final fun getAndroid ()Lcom/google/firebase/auth/AdditionalUserInfo; public final fun getProfile ()Ljava/util/Map; public final fun getProviderId ()Ljava/lang/String; public final fun getUsername ()Ljava/lang/String; @@ -290,6 +289,7 @@ public final class dev/gitlive/firebase/auth/UserMetaData { public final class dev/gitlive/firebase/auth/android { public static final fun auth (Ldev/gitlive/firebase/Firebase;Ldev/gitlive/firebase/FirebaseApp;)Ldev/gitlive/firebase/auth/FirebaseAuth; + public static final fun getAndroid (Ldev/gitlive/firebase/auth/AdditionalUserInfo;)Lcom/google/firebase/auth/AdditionalUserInfo; public static final fun getAndroid (Ldev/gitlive/firebase/auth/AuthResult;)Lcom/google/firebase/auth/AuthResult; public static final fun getAndroid (Ldev/gitlive/firebase/auth/AuthTokenResult;)Lcom/google/firebase/auth/GetTokenResult; public static final fun getAndroid (Ldev/gitlive/firebase/auth/FirebaseAuth;)Lcom/google/firebase/auth/FirebaseAuth; diff --git a/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 045e683c6..cc4f2957d 100644 --- a/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/androidMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -127,8 +127,11 @@ public actual class AuthResult(internal val android: com.google.firebase.auth.Au get() = android.additionalUserInfo?.let { AdditionalUserInfo(it) } } +public val AdditionalUserInfo.android: com.google.firebase.auth.AdditionalUserInfo + get() = android + public actual class AdditionalUserInfo( - public val android: com.google.firebase.auth.AdditionalUserInfo, + internal val android: com.google.firebase.auth.AdditionalUserInfo, ) { public actual val providerId: String? get() = android.providerId diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 71cca6ed8..b7588fe80 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -117,8 +117,10 @@ public actual class AuthResult(internal val ios: FIRAuthDataResult) { get() = ios.additionalUserInfo?.let { AdditionalUserInfo(it) } } +public val AdditionalUserInfo.ios: FIRAdditionalUserInfo get() = ios + public actual class AdditionalUserInfo( - public val ios: FIRAdditionalUserInfo, + internal val ios: FIRAdditionalUserInfo, ) { public actual val providerId: String? get() = ios.providerID diff --git a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 4442d2661..4d0223d28 100644 --- a/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -144,8 +144,10 @@ public actual class AuthResult(internal val js: JsAuthResult) { get() = rethrow { js.additionalUserInfo?.let { AdditionalUserInfo(it) } } } +public val AdditionalUserInfo.js: JsAdditionalUserInfo get() = js + public actual class AdditionalUserInfo( - public val js: JsAdditionalUserInfo, + internal val js: JsAdditionalUserInfo, ) { public actual val providerId: String? get() = js.providerId From 9e8ef049386baf9a73f979de6a6ac43f68930d2b Mon Sep 17 00:00:00 2001 From: Nicholas Bransby-Williams Date: Fri, 30 Aug 2024 08:11:59 +0100 Subject: [PATCH 21/33] Update auth.kt --- .../iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt index 7d6798822..30ff27bc1 100644 --- a/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt +++ b/firebase-auth/src/iosMain/kotlin/dev/gitlive/firebase/auth/auth.kt @@ -112,9 +112,9 @@ public actual class AuthResult(internal val ios: FIRAuthDataResult) { public actual val user: FirebaseUser? get() = FirebaseUser(ios.user()) public actual val credential: AuthCredential? - get() = ios.credential?.let { AuthCredential(it) } + get() = ios.credential()?.let { AuthCredential(it) } public actual val additionalUserInfo: AdditionalUserInfo? - get() = ios.additionalUserInfo?.let { AdditionalUserInfo(it) } + get() = ios.additionalUserInfo()?.let { AdditionalUserInfo(it) } } public val AdditionalUserInfo.ios: FIRAdditionalUserInfo get() = ios @@ -123,11 +123,11 @@ public actual class AdditionalUserInfo( internal val ios: FIRAdditionalUserInfo, ) { public actual val providerId: String? - get() = ios.providerID + get() = ios.providerID() public actual val username: String? - get() = ios.username + get() = ios.username() public actual val profile: Map? - get() = ios.profile + get() = ios.profile() ?.mapNotNull { (key, value) -> if (key is NSString && value != null) { key.toString() to value @@ -137,7 +137,7 @@ public actual class AdditionalUserInfo( } ?.toMap() public actual val isNewUser: Boolean - get() = ios.newUser + get() = ios.newUser() } public val AuthTokenResult.ios: FIRAuthTokenResult get() = ios From 1c28ed3bbe15d85f7b329862626575833b9c4f71 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Fri, 30 Aug 2024 10:54:13 +0200 Subject: [PATCH 22/33] Adding support for encoded queries --- .../firestore/internal/NativeQueryWrapper.kt | 12 +- .../dev/gitlive/firebase/firestore/Filter.kt | 254 ++++++++++++++---- .../gitlive/firebase/firestore/firestore.kt | 9 +- .../firebase/firestore/internal/SafeValue.kt | 14 - .../gitlive/firebase/firestore/firestore.kt | 18 +- .../firestore/internal/NativeQueryWrapper.kt | 40 +-- .../firestore/internal/NativeQueryWrapper.kt | 12 +- 7 files changed, 252 insertions(+), 107 deletions(-) delete mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/SafeValue.kt diff --git a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt index 5dc17f72b..7505e09ef 100644 --- a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt +++ b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt @@ -59,7 +59,7 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is WhereConstraint.EqualTo -> com.google.firebase.firestore.Filter::equalTo is WhereConstraint.NotEqualTo -> com.google.firebase.firestore.Filter::notEqualTo } - modifier.invoke(field, constraint.safeValue) + modifier.invoke(field, constraint.value) } is WhereConstraint.ForObject -> { val modifier: (String, Any) -> com.google.firebase.firestore.Filter = when (constraint) { @@ -69,7 +69,7 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is WhereConstraint.GreaterThanOrEqualTo -> com.google.firebase.firestore.Filter::greaterThanOrEqualTo is WhereConstraint.ArrayContains -> com.google.firebase.firestore.Filter::arrayContains } - modifier.invoke(field, constraint.safeValue) + modifier.invoke(field, constraint.value) } is WhereConstraint.ForArray -> { val modifier: (String, List) -> com.google.firebase.firestore.Filter = when (constraint) { @@ -77,7 +77,7 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is WhereConstraint.ArrayContainsAny -> com.google.firebase.firestore.Filter::arrayContainsAny is WhereConstraint.NotInArray -> com.google.firebase.firestore.Filter::notInArray } - modifier.invoke(field, constraint.safeValues) + modifier.invoke(field, constraint.values) } } } @@ -88,7 +88,7 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is WhereConstraint.EqualTo -> com.google.firebase.firestore.Filter::equalTo is WhereConstraint.NotEqualTo -> com.google.firebase.firestore.Filter::notEqualTo } - modifier.invoke(path.android, constraint.safeValue) + modifier.invoke(path.android, constraint.value) } is WhereConstraint.ForObject -> { val modifier: (FieldPath, Any) -> com.google.firebase.firestore.Filter = when (constraint) { @@ -98,7 +98,7 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is WhereConstraint.GreaterThanOrEqualTo -> com.google.firebase.firestore.Filter::greaterThanOrEqualTo is WhereConstraint.ArrayContains -> com.google.firebase.firestore.Filter::arrayContains } - modifier.invoke(path.android, constraint.safeValue) + modifier.invoke(path.android, constraint.value) } is WhereConstraint.ForArray -> { val modifier: (FieldPath, List) -> com.google.firebase.firestore.Filter = when (constraint) { @@ -106,7 +106,7 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is WhereConstraint.ArrayContainsAny -> com.google.firebase.firestore.Filter::arrayContainsAny is WhereConstraint.NotInArray -> com.google.firebase.firestore.Filter::notInArray } - modifier.invoke(path.android, constraint.safeValues) + modifier.invoke(path.android, constraint.values) } } } diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt index f9e8558e7..4ad37abea 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt @@ -1,33 +1,31 @@ package dev.gitlive.firebase.firestore -import dev.gitlive.firebase.firestore.internal.safeValue +import dev.gitlive.firebase.EncodeSettings +import kotlinx.serialization.SerializationStrategy public sealed interface WhereConstraint { public sealed interface ForNullableObject : WhereConstraint { public val value: Any? - public val safeValue: Any? get() = value?.safeValue } public sealed interface ForObject : WhereConstraint { public val value: Any - public val safeValue: Any get() = value.safeValue } public sealed interface ForArray : WhereConstraint { public val values: List - public val safeValues: List get() = values.map { it.safeValue } } - public data class EqualTo internal constructor(override val value: Any?) : ForNullableObject - public data class NotEqualTo internal constructor(override val value: Any?) : ForNullableObject - public data class LessThan internal constructor(override val value: Any) : ForObject - public data class GreaterThan internal constructor(override val value: Any) : ForObject - public data class LessThanOrEqualTo internal constructor(override val value: Any) : ForObject - public data class GreaterThanOrEqualTo internal constructor(override val value: Any) : ForObject - public data class ArrayContains internal constructor(override val value: Any) : ForObject - public data class ArrayContainsAny internal constructor(override val values: List) : ForArray - public data class InArray internal constructor(override val values: List) : ForArray - public data class NotInArray internal constructor(override val values: List) : ForArray + public data class EqualTo @PublishedApi internal constructor(override val value: Any?) : ForNullableObject + public data class NotEqualTo @PublishedApi internal constructor(override val value: Any?) : ForNullableObject + public data class LessThan @PublishedApi internal constructor(override val value: Any) : ForObject + public data class GreaterThan @PublishedApi internal constructor(override val value: Any) : ForObject + public data class LessThanOrEqualTo @PublishedApi internal constructor(override val value: Any) : ForObject + public data class GreaterThanOrEqualTo @PublishedApi internal constructor(override val value: Any) : ForObject + public data class ArrayContains @PublishedApi internal constructor(override val value: Any) : ForObject + public data class ArrayContainsAny @PublishedApi internal constructor(override val values: List) : ForArray + public data class InArray @PublishedApi internal constructor(override val values: List) : ForArray + public data class NotInArray @PublishedApi internal constructor(override val values: List) : ForArray } public sealed class Filter { @@ -37,51 +35,199 @@ public sealed class Filter { public abstract val constraint: WhereConstraint } - public data class Field internal constructor(val field: String, override val constraint: WhereConstraint) : WithConstraint() - public data class Path internal constructor(val path: FieldPath, override val constraint: WhereConstraint) : WithConstraint() + public data class Field @PublishedApi internal constructor(val field: String, override val constraint: WhereConstraint) : WithConstraint() + public data class Path @PublishedApi internal constructor(val path: FieldPath, override val constraint: WhereConstraint) : WithConstraint() } public class FilterBuilder internal constructor() { - public infix fun String.equalTo(value: Any?): Filter.WithConstraint = Filter.Field(this, WhereConstraint.EqualTo(value)) - - public infix fun FieldPath.equalTo(value: Any?): Filter.WithConstraint = Filter.Path(this, WhereConstraint.EqualTo(value)) - - public infix fun String.notEqualTo(value: Any?): Filter.WithConstraint = Filter.Field(this, WhereConstraint.NotEqualTo(value)) - - public infix fun FieldPath.notEqualTo(value: Any?): Filter.WithConstraint = Filter.Path(this, WhereConstraint.NotEqualTo(value)) - - public infix fun String.lessThan(value: Any): Filter.WithConstraint = Filter.Field(this, WhereConstraint.LessThan(value)) - - public infix fun FieldPath.lessThan(value: Any): Filter.WithConstraint = Filter.Path(this, WhereConstraint.LessThan(value)) - - public infix fun String.greaterThan(value: Any): Filter.WithConstraint = Filter.Field(this, WhereConstraint.GreaterThan(value)) - - public infix fun FieldPath.greaterThan(value: Any): Filter.WithConstraint = Filter.Path(this, WhereConstraint.GreaterThan(value)) - - public infix fun String.lessThanOrEqualTo(value: Any): Filter.WithConstraint = Filter.Field(this, WhereConstraint.LessThanOrEqualTo(value)) - - public infix fun FieldPath.lessThanOrEqualTo(value: Any): Filter.WithConstraint = Filter.Path(this, WhereConstraint.LessThanOrEqualTo(value)) - - public infix fun String.greaterThanOrEqualTo(value: Any): Filter.WithConstraint = Filter.Field(this, WhereConstraint.GreaterThanOrEqualTo(value)) - - public infix fun FieldPath.greaterThanOrEqualTo(value: Any): Filter.WithConstraint = Filter.Path(this, WhereConstraint.GreaterThanOrEqualTo(value)) - - public infix fun String.contains(value: Any): Filter.WithConstraint = Filter.Field(this, WhereConstraint.ArrayContains(value)) - - public infix fun FieldPath.contains(value: Any): Filter.WithConstraint = Filter.Path(this, WhereConstraint.ArrayContains(value)) - - public infix fun String.containsAny(values: List): Filter.WithConstraint = Filter.Field(this, WhereConstraint.ArrayContainsAny(values)) - - public infix fun FieldPath.containsAny(values: List): Filter.WithConstraint = Filter.Path(this, WhereConstraint.ArrayContainsAny(values)) - - public infix fun String.inArray(values: List): Filter.WithConstraint = Filter.Field(this, WhereConstraint.InArray(values)) - - public infix fun FieldPath.inArray(values: List): Filter.WithConstraint = Filter.Path(this, WhereConstraint.InArray(values)) - - public infix fun String.notInArray(values: List): Filter.WithConstraint = Filter.Field(this, WhereConstraint.NotInArray(values)) + public var buildSettings: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } - public infix fun FieldPath.notInArray(values: List): Filter.WithConstraint = Filter.Path(this, WhereConstraint.NotInArray(values)) + public val String.isNull: Filter.WithConstraint get() = Filter.Field(this, WhereConstraint.EqualTo(null)) + public inline infix fun String.equalTo(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.EqualTo(encode(value, buildSettings)) + ) + public fun String.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + ) + + public val FieldPath.isNull: Filter.WithConstraint get() = Filter.Path(this, WhereConstraint.EqualTo(null)) + public inline infix fun FieldPath.equalTo(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.EqualTo(encode(value, buildSettings)) + ) + public fun FieldPath.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + ) + + public val String.isNotNull: Filter.WithConstraint get() = Filter.Field(this, WhereConstraint.NotEqualTo(null)) + public inline infix fun String.notEqualTo(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.NotEqualTo(encode(value, buildSettings)) + ) + public fun String.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + ) + + public val FieldPath.isNotNull: Filter.WithConstraint get() = Filter.Path(this, WhereConstraint.NotEqualTo(null)) + public inline infix fun FieldPath.notEqualTo(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.NotEqualTo(encode(value, buildSettings)) + ) + public fun FieldPath.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + ) + + public inline infix fun String.lessThan(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.LessThan(encode(value, buildSettings)!!) + ) + public fun String.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun FieldPath.lessThan(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.LessThan(encode(value, buildSettings)!!) + ) + public fun FieldPath.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun String.greaterThan(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.GreaterThan(encode(value, buildSettings)!!) + ) + public fun String.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun FieldPath.greaterThan(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.GreaterThan(encode(value, buildSettings)!!) + ) + public fun FieldPath.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun String.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!) + ) + public fun String.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun FieldPath.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!) + ) + public fun FieldPath.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun String.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!) + ) + public fun String.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun FieldPath.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!) + ) + public fun FieldPath.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun String.contains(value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.ArrayContains(encode(value, buildSettings)!!) + ) + public fun String.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun FieldPath.contains(value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.ArrayContains(encode(value, buildSettings)!!) + ) + public fun FieldPath.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + ) + + public inline infix fun String.containsAny(values: List): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.ArrayContainsAny(values.map { encode(it, buildSettings)!! }) + ) + public fun String.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.ArrayContainsAny(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + ) + + public inline infix fun FieldPath.containsAny(values: List): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.ArrayContainsAny(values.map { encode(it, buildSettings)!! }) + ) + public fun FieldPath.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.ArrayContainsAny(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + ) + + public inline infix fun String.inArray(values: List): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.InArray(values.map { encode(it, buildSettings)!! }) + ) + public fun String.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.InArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + ) + + public inline infix fun FieldPath.inArray(values: List): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.InArray(values.map { encode(it, buildSettings)!! }) + ) + public fun FieldPath.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.InArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + ) + + public inline infix fun String.notInArray(values: List): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.NotInArray(values.map { encode(it, buildSettings)!! }) + ) + public fun String.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( + this, + WhereConstraint.NotInArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + ) + + public inline infix fun FieldPath.notInArray(values: List): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.NotInArray(values.map { encode(it, buildSettings)!! }) + ) + public fun FieldPath.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( + this, + WhereConstraint.NotInArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + ) public infix fun Filter.and(right: Filter): Filter.And { val leftList = when (this) { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index bf4723e49..795c481b1 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -18,7 +18,6 @@ import dev.gitlive.firebase.firestore.internal.NativeQueryWrapper import dev.gitlive.firebase.firestore.internal.NativeTransactionWrapper import dev.gitlive.firebase.firestore.internal.NativeWriteBatchWrapper import dev.gitlive.firebase.firestore.internal.SetOptions -import dev.gitlive.firebase.firestore.internal.safeValue import dev.gitlive.firebase.internal.decode import dev.gitlive.firebase.internal.encodeAsObject import kotlinx.coroutines.flow.Flow @@ -230,14 +229,14 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun orderBy(field: FieldPath, direction: Direction = Direction.ASCENDING): Query = Query(nativeQuery.orderBy(field.encoded, direction)) public fun startAfter(document: DocumentSnapshot): Query = Query(nativeQuery.startAfter(document.native)) - public fun startAfter(vararg fieldValues: Any): Query = Query(nativeQuery.startAfter(*(fieldValues.map { it.safeValue }.toTypedArray()))) + public fun startAfter(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAfter(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) public fun startAt(document: DocumentSnapshot): Query = Query(nativeQuery.startAt(document.native)) - public fun startAt(vararg fieldValues: Any): Query = Query(nativeQuery.startAt(*(fieldValues.map { it.safeValue }.toTypedArray()))) + public fun startAt(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAt(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) public fun endBefore(document: DocumentSnapshot): Query = Query(nativeQuery.endBefore(document.native)) - public fun endBefore(vararg fieldValues: Any): Query = Query(nativeQuery.endBefore(*(fieldValues.map { it.safeValue }.toTypedArray()))) + public fun endBefore(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endBefore(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) public fun endAt(document: DocumentSnapshot): Query = Query(nativeQuery.endAt(document.native)) - public fun endAt(vararg fieldValues: Any): Query = Query(nativeQuery.endAt(*(fieldValues.map { it.safeValue }.toTypedArray()))) + public fun endAt(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endAt(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) } @Deprecated("Deprecated in favor of using a [FilterBuilder]", replaceWith = ReplaceWith("where { field equalTo equalTo }", "dev.gitlive.firebase.firestore")) diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/SafeValue.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/SafeValue.kt deleted file mode 100644 index afca32060..000000000 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/SafeValue.kt +++ /dev/null @@ -1,14 +0,0 @@ -package dev.gitlive.firebase.firestore.internal - -import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.GeoPoint -import dev.gitlive.firebase.firestore.Timestamp - -internal val Any.safeValue: Any get() = when (this) { - is Timestamp -> nativeValue - is GeoPoint -> nativeValue - is DocumentReference -> native.nativeValue - is Map<*, *> -> this.mapNotNull { (key, value) -> key?.let { it.safeValue to value?.safeValue } } - is Collection<*> -> this.mapNotNull { it?.safeValue } - else -> this -} diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 99148d8cc..672d5f0ea 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -55,6 +55,8 @@ class FirebaseFirestoreTest { val count: Int = 0, val list: List = emptyList(), val optional: String? = null, + val nested: NestedObject? = null, + val nestedList: List = emptyList(), ) @Serializable @@ -63,6 +65,11 @@ class FirebaseFirestoreTest { val time: BaseTimestamp?, ) + @Serializable + data class NestedObject( + val prop2: String + ) + companion object { val testOne = FirestoreTest( "aaa", @@ -70,12 +77,17 @@ class FirebaseFirestoreTest { 1, listOf("a", "aa", "aaa"), "notNull", + NestedObject("ddd"), + listOf(NestedObject("l1"), NestedObject("l2"), NestedObject("l3")), ) val testTwo = FirestoreTest( "bbb", 0.0, 2, listOf("b", "bb", "ccc"), + null, + NestedObject("eee"), + listOf(NestedObject("l2"), NestedObject("l4"), NestedObject("l5")), ) val testThree = FirestoreTest( "ccc", @@ -83,6 +95,8 @@ class FirebaseFirestoreTest { 3, listOf("c", "cc", "ccc"), "notNull", + NestedObject("fff"), + listOf(NestedObject("l6"), NestedObject("l7"), NestedObject("l8")), ) } @@ -828,7 +842,7 @@ class FirebaseFirestoreTest { val nullableQuery = firestore .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::optional.name) equalTo null } + .where { FieldPath(FirestoreTest::optional.name).isNull } nullableQuery.assertDocuments(FirestoreTest.serializer(), testTwo) } @@ -851,7 +865,7 @@ class FirebaseFirestoreTest { val nullableQuery = firestore .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::optional.name) notEqualTo null } + .where { FieldPath(FirestoreTest::optional.name).isNotNull } nullableQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) } diff --git a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt index 30f01b7f1..f17bf14c8 100644 --- a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt +++ b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt @@ -45,28 +45,28 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is Filter.And -> FIRFilter.andFilterWithFilters(filters.map { it.toFIRFilter() }) is Filter.Or -> FIRFilter.orFilterWithFilters(filters.map { it.toFIRFilter() }) is Filter.Field -> when (constraint) { - is WhereConstraint.EqualTo -> FIRFilter.filterWhereField(field, isEqualTo = constraint.safeValue ?: NSNull.`null`()) - is WhereConstraint.NotEqualTo -> FIRFilter.filterWhereField(field, isNotEqualTo = constraint.safeValue ?: NSNull.`null`()) - is WhereConstraint.LessThan -> FIRFilter.filterWhereField(field, isLessThan = constraint.safeValue) - is WhereConstraint.GreaterThan -> FIRFilter.filterWhereField(field, isGreaterThan = constraint.safeValue) - is WhereConstraint.LessThanOrEqualTo -> FIRFilter.filterWhereField(field, isLessThanOrEqualTo = constraint.safeValue) - is WhereConstraint.GreaterThanOrEqualTo -> FIRFilter.filterWhereField(field, isGreaterThanOrEqualTo = constraint.safeValue) - is WhereConstraint.ArrayContains -> FIRFilter.filterWhereField(field, arrayContains = constraint.safeValue) - is WhereConstraint.ArrayContainsAny -> FIRFilter.filterWhereField(field, arrayContainsAny = constraint.safeValues) - is WhereConstraint.InArray -> FIRFilter.filterWhereField(field, `in` = constraint.safeValues) - is WhereConstraint.NotInArray -> FIRFilter.filterWhereField(field, notIn = constraint.safeValues) + is WhereConstraint.EqualTo -> FIRFilter.filterWhereField(field, isEqualTo = constraint.value ?: NSNull.`null`()) + is WhereConstraint.NotEqualTo -> FIRFilter.filterWhereField(field, isNotEqualTo = constraint.value ?: NSNull.`null`()) + is WhereConstraint.LessThan -> FIRFilter.filterWhereField(field, isLessThan = constraint.value) + is WhereConstraint.GreaterThan -> FIRFilter.filterWhereField(field, isGreaterThan = constraint.value) + is WhereConstraint.LessThanOrEqualTo -> FIRFilter.filterWhereField(field, isLessThanOrEqualTo = constraint.value) + is WhereConstraint.GreaterThanOrEqualTo -> FIRFilter.filterWhereField(field, isGreaterThanOrEqualTo = constraint.value) + is WhereConstraint.ArrayContains -> FIRFilter.filterWhereField(field, arrayContains = constraint.value) + is WhereConstraint.ArrayContainsAny -> FIRFilter.filterWhereField(field, arrayContainsAny = constraint.values) + is WhereConstraint.InArray -> FIRFilter.filterWhereField(field, `in` = constraint.values) + is WhereConstraint.NotInArray -> FIRFilter.filterWhereField(field, notIn = constraint.values) } is Filter.Path -> when (constraint) { - is WhereConstraint.EqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isEqualTo = constraint.safeValue ?: NSNull.`null`()) - is WhereConstraint.NotEqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isNotEqualTo = constraint.safeValue ?: NSNull.`null`()) - is WhereConstraint.LessThan -> FIRFilter.filterWhereFieldPath(path.ios, isLessThan = constraint.safeValue) - is WhereConstraint.GreaterThan -> FIRFilter.filterWhereFieldPath(path.ios, isGreaterThan = constraint.safeValue) - is WhereConstraint.LessThanOrEqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isLessThanOrEqualTo = constraint.safeValue) - is WhereConstraint.GreaterThanOrEqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isGreaterThanOrEqualTo = constraint.safeValue) - is WhereConstraint.ArrayContains -> FIRFilter.filterWhereFieldPath(path.ios, arrayContains = constraint.safeValue) - is WhereConstraint.ArrayContainsAny -> FIRFilter.filterWhereFieldPath(path.ios, arrayContainsAny = constraint.safeValues) - is WhereConstraint.InArray -> FIRFilter.filterWhereFieldPath(path.ios, `in` = constraint.safeValues) - is WhereConstraint.NotInArray -> FIRFilter.filterWhereFieldPath(path.ios, notIn = constraint.safeValues) + is WhereConstraint.EqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isEqualTo = constraint.value ?: NSNull.`null`()) + is WhereConstraint.NotEqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isNotEqualTo = constraint.value ?: NSNull.`null`()) + is WhereConstraint.LessThan -> FIRFilter.filterWhereFieldPath(path.ios, isLessThan = constraint.value) + is WhereConstraint.GreaterThan -> FIRFilter.filterWhereFieldPath(path.ios, isGreaterThan = constraint.value) + is WhereConstraint.LessThanOrEqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isLessThanOrEqualTo = constraint.value) + is WhereConstraint.GreaterThanOrEqualTo -> FIRFilter.filterWhereFieldPath(path.ios, isGreaterThanOrEqualTo = constraint.value) + is WhereConstraint.ArrayContains -> FIRFilter.filterWhereFieldPath(path.ios, arrayContains = constraint.value) + is WhereConstraint.ArrayContainsAny -> FIRFilter.filterWhereFieldPath(path.ios, arrayContainsAny = constraint.values) + is WhereConstraint.InArray -> FIRFilter.filterWhereFieldPath(path.ios, `in` = constraint.values) + is WhereConstraint.NotInArray -> FIRFilter.filterWhereFieldPath(path.ios, notIn = constraint.values) } } diff --git a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt index bc49b3437..04327dfd1 100644 --- a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt +++ b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeQueryWrapper.kt @@ -45,17 +45,17 @@ internal actual open class NativeQueryWrapper internal actual constructor(actual is Filter.Or -> or(*filters.map { it.toQueryConstraint() }.toTypedArray()) is Filter.Field -> { val value = when (constraint) { - is WhereConstraint.ForNullableObject -> constraint.safeValue - is WhereConstraint.ForObject -> constraint.safeValue - is WhereConstraint.ForArray -> constraint.safeValues.toTypedArray() + is WhereConstraint.ForNullableObject -> constraint.value + is WhereConstraint.ForObject -> constraint.value + is WhereConstraint.ForArray -> constraint.values.toTypedArray() } dev.gitlive.firebase.firestore.externals.where(field, constraint.filterOp, value) } is Filter.Path -> { val value = when (constraint) { - is WhereConstraint.ForNullableObject -> constraint.safeValue - is WhereConstraint.ForObject -> constraint.safeValue - is WhereConstraint.ForArray -> constraint.safeValues.toTypedArray() + is WhereConstraint.ForNullableObject -> constraint.value + is WhereConstraint.ForObject -> constraint.value + is WhereConstraint.ForArray -> constraint.values.toTypedArray() } dev.gitlive.firebase.firestore.externals.where(path.js, constraint.filterOp, value) } From bf8680cce35f0b4da9e3d52dc5e61222596f81b6 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Fri, 30 Aug 2024 12:20:04 +0200 Subject: [PATCH 23/33] Add support for customizing encoding behaviour when updating Values at paths --- .../api/android/firebase-common.api | 17 --- firebase-common/api/jvm/firebase-common.api | 17 --- .../api/android/firebase-firestore.api | 130 +++++++++++------- .../api/jvm/firebase-firestore.api | 130 +++++++++++------- .../firebase/firestore/EncodableValue.kt | 13 ++ .../dev/gitlive/firebase/firestore/Filter.kt | 80 +++++------ .../gitlive/firebase/firestore/firestore.kt | 72 ++++++++-- .../dev/gitlive/firebase/firestore/helpers.kt | 18 +-- .../gitlive/firebase/firestore/firestore.kt | 5 +- 9 files changed, 288 insertions(+), 194 deletions(-) create mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt diff --git a/firebase-common/api/android/firebase-common.api b/firebase-common/api/android/firebase-common.api index 9724b86d4..14df6bc61 100644 --- a/firebase-common/api/android/firebase-common.api +++ b/firebase-common/api/android/firebase-common.api @@ -51,20 +51,3 @@ public final class dev/gitlive/firebase/FirebaseEncoder$DefaultImpls { public static fun encodeSerializableValue (Ldev/gitlive/firebase/FirebaseEncoder;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/ValueWithSerializer { - public fun (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)V - public final fun component1 ()Ljava/lang/Object; - public final fun component2 ()Lkotlinx/serialization/SerializationStrategy; - public final fun copy (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ldev/gitlive/firebase/ValueWithSerializer; - public static synthetic fun copy$default (Ldev/gitlive/firebase/ValueWithSerializer;Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;ILjava/lang/Object;)Ldev/gitlive/firebase/ValueWithSerializer; - public fun equals (Ljava/lang/Object;)Z - public final fun getSerializer ()Lkotlinx/serialization/SerializationStrategy; - public final fun getValue ()Ljava/lang/Object; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class dev/gitlive/firebase/ValueWithSerializerKt { - public static final fun withSerializer (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ljava/lang/Object; -} - diff --git a/firebase-common/api/jvm/firebase-common.api b/firebase-common/api/jvm/firebase-common.api index 9724b86d4..14df6bc61 100644 --- a/firebase-common/api/jvm/firebase-common.api +++ b/firebase-common/api/jvm/firebase-common.api @@ -51,20 +51,3 @@ public final class dev/gitlive/firebase/FirebaseEncoder$DefaultImpls { public static fun encodeSerializableValue (Ldev/gitlive/firebase/FirebaseEncoder;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/ValueWithSerializer { - public fun (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)V - public final fun component1 ()Ljava/lang/Object; - public final fun component2 ()Lkotlinx/serialization/SerializationStrategy; - public final fun copy (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ldev/gitlive/firebase/ValueWithSerializer; - public static synthetic fun copy$default (Ldev/gitlive/firebase/ValueWithSerializer;Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;ILjava/lang/Object;)Ldev/gitlive/firebase/ValueWithSerializer; - public fun equals (Ljava/lang/Object;)Z - public final fun getSerializer ()Lkotlinx/serialization/SerializationStrategy; - public final fun getValue ()Ljava/lang/Object; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class dev/gitlive/firebase/ValueWithSerializerKt { - public static final fun withSerializer (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ljava/lang/Object; -} - diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index 8a0aa2e9a..9dea82602 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -76,8 +76,12 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun updateEncodedFieldsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun updateFieldPathsWithEncodableValue ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun updateFieldsWithEncodableValues ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun updateFieldsWithEncodableValues$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -131,6 +135,21 @@ public final class dev/gitlive/firebase/firestore/DoubleAsTimestampSerializer : public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public final class dev/gitlive/firebase/firestore/EncodableValue { + public fun (Lkotlin/jvm/functions/Function1;)V + public final fun component1 ()Lkotlin/jvm/functions/Function1; + public final fun copy (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/EncodableValue; + public static synthetic fun copy$default (Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/EncodableValue; + public fun equals (Ljava/lang/Object;)Z + public final fun getEncoded ()Lkotlin/jvm/functions/Function1; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class dev/gitlive/firebase/firestore/EncodableValueKt { + public static final fun encodableWithStrategy (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ldev/gitlive/firebase/firestore/EncodableValue; +} + public final class dev/gitlive/firebase/firestore/FieldPath { public static final field Companion Ldev/gitlive/firebase/firestore/FieldPath$Companion; public fun ([Ljava/lang/String;)V @@ -182,6 +201,7 @@ public final class dev/gitlive/firebase/firestore/Filter$And : dev/gitlive/fireb } public final class dev/gitlive/firebase/firestore/Filter$Field : dev/gitlive/firebase/firestore/Filter$WithConstraint { + public fun (Ljava/lang/String;Ldev/gitlive/firebase/firestore/WhereConstraint;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Ldev/gitlive/firebase/firestore/WhereConstraint; public fun equals (Ljava/lang/Object;)Z @@ -200,6 +220,7 @@ public final class dev/gitlive/firebase/firestore/Filter$Or : dev/gitlive/fireba } public final class dev/gitlive/firebase/firestore/Filter$Path : dev/gitlive/firebase/firestore/Filter$WithConstraint { + public fun (Ldev/gitlive/firebase/firestore/FieldPath;Ldev/gitlive/firebase/firestore/WhereConstraint;)V public final fun component1 ()Ldev/gitlive/firebase/firestore/FieldPath; public final fun component2 ()Ldev/gitlive/firebase/firestore/WhereConstraint; public fun equals (Ljava/lang/Object;)Z @@ -217,27 +238,33 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { public final fun all ([Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter; public final fun and (Ldev/gitlive/firebase/firestore/Filter;Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter$And; public final fun any ([Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter; - public final fun contains (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun contains (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun containsAny (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun containsAny (Ljava/lang/String;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun equalTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun equalTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThan (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThan (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThanOrEqualTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun inArray (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun inArray (Ljava/lang/String;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThan (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThan (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThanOrEqualTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notEqualTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notInArray (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notInArray (Ljava/lang/String;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun contains (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun contains (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun containsAny (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun containsAny (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun equalTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun equalTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; + public final fun greaterThan (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun greaterThan (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun greaterThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun greaterThanOrEqualTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun inArray (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun inArray (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNotNull (Ldev/gitlive/firebase/firestore/FieldPath;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNotNull (Ljava/lang/String;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNull (Ldev/gitlive/firebase/firestore/FieldPath;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNull (Ljava/lang/String;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThan (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThan (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThanOrEqualTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notEqualTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notInArray (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notInArray (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; public final fun or (Ldev/gitlive/firebase/firestore/Filter;Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter$Or; + public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V } public final class dev/gitlive/firebase/firestore/FirebaseFirestore { @@ -424,9 +451,15 @@ public final class dev/gitlive/firebase/firestore/MemoryGarbageCollectorSettings public class dev/gitlive/firebase/firestore/Query { public static final field Companion Ldev/gitlive/firebase/firestore/Query$Companion; public final fun endAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun endAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun endBefore ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endBefore$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBeforeWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endBeforeWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun get (Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun get$default (Ldev/gitlive/firebase/firestore/Query;Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getSnapshots ()Lkotlinx/coroutines/flow/Flow; @@ -438,9 +471,15 @@ public class dev/gitlive/firebase/firestore/Query { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/Query;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public final fun startAfter (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAfter ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAfter$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfterWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAfterWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun where (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; } @@ -565,8 +604,12 @@ public final class dev/gitlive/firebase/firestore/Transaction { public final fun updateEncodedFieldsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldPathsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public static synthetic fun updateFieldsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -576,117 +619,102 @@ public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint { } public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContains : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContainsAny : dev/gitlive/firebase/firestore/WhereConstraint$ForArray { + public fun (Ljava/util/List;)V public final fun component1 ()Ljava/util/List; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValues ()Ljava/util/List; public fun getValues ()Ljava/util/List; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$EqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$ForArray : dev/gitlive/firebase/firestore/WhereConstraint { - public abstract fun getSafeValues ()Ljava/util/List; public abstract fun getValues ()Ljava/util/List; } -public final class dev/gitlive/firebase/firestore/WhereConstraint$ForArray$DefaultImpls { - public static fun getSafeValues (Ldev/gitlive/firebase/firestore/WhereConstraint$ForArray;)Ljava/util/List; -} - public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject : dev/gitlive/firebase/firestore/WhereConstraint { - public abstract fun getSafeValue ()Ljava/lang/Object; public abstract fun getValue ()Ljava/lang/Object; } -public final class dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject$DefaultImpls { - public static fun getSafeValue (Ldev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject;)Ljava/lang/Object; -} - public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$ForObject : dev/gitlive/firebase/firestore/WhereConstraint { - public abstract fun getSafeValue ()Ljava/lang/Object; public abstract fun getValue ()Ljava/lang/Object; } -public final class dev/gitlive/firebase/firestore/WhereConstraint$ForObject$DefaultImpls { - public static fun getSafeValue (Ldev/gitlive/firebase/firestore/WhereConstraint$ForObject;)Ljava/lang/Object; -} - public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThan : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThanOrEqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$InArray : dev/gitlive/firebase/firestore/WhereConstraint$ForArray { + public fun (Ljava/util/List;)V public final fun component1 ()Ljava/util/List; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValues ()Ljava/util/List; public fun getValues ()Ljava/util/List; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThan : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThanOrEqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$NotEqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$NotInArray : dev/gitlive/firebase/firestore/WhereConstraint$ForArray { + public fun (Ljava/util/List;)V public final fun component1 ()Ljava/util/List; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValues ()Ljava/util/List; public fun getValues ()Ljava/util/List; public fun hashCode ()I public fun toString ()Ljava/lang/String; @@ -720,6 +748,10 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldPathWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; + public static synthetic fun updateFieldPathWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; + public static synthetic fun updateFieldWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 33a64aef7..ccf423cda 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -76,8 +76,12 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun updateEncodedFieldsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun updateFieldPathsWithEncodableValue ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun updateFieldsWithEncodableValues ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun updateFieldsWithEncodableValues$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -131,6 +135,21 @@ public final class dev/gitlive/firebase/firestore/DoubleAsTimestampSerializer : public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public final class dev/gitlive/firebase/firestore/EncodableValue { + public fun (Lkotlin/jvm/functions/Function1;)V + public final fun component1 ()Lkotlin/jvm/functions/Function1; + public final fun copy (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/EncodableValue; + public static synthetic fun copy$default (Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/EncodableValue; + public fun equals (Ljava/lang/Object;)Z + public final fun getEncoded ()Lkotlin/jvm/functions/Function1; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class dev/gitlive/firebase/firestore/EncodableValueKt { + public static final fun encodableWithStrategy (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ldev/gitlive/firebase/firestore/EncodableValue; +} + public final class dev/gitlive/firebase/firestore/FieldPath { public static final field Companion Ldev/gitlive/firebase/firestore/FieldPath$Companion; public fun ([Ljava/lang/String;)V @@ -182,6 +201,7 @@ public final class dev/gitlive/firebase/firestore/Filter$And : dev/gitlive/fireb } public final class dev/gitlive/firebase/firestore/Filter$Field : dev/gitlive/firebase/firestore/Filter$WithConstraint { + public fun (Ljava/lang/String;Ldev/gitlive/firebase/firestore/WhereConstraint;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Ldev/gitlive/firebase/firestore/WhereConstraint; public fun equals (Ljava/lang/Object;)Z @@ -200,6 +220,7 @@ public final class dev/gitlive/firebase/firestore/Filter$Or : dev/gitlive/fireba } public final class dev/gitlive/firebase/firestore/Filter$Path : dev/gitlive/firebase/firestore/Filter$WithConstraint { + public fun (Ldev/gitlive/firebase/firestore/FieldPath;Ldev/gitlive/firebase/firestore/WhereConstraint;)V public final fun component1 ()Ldev/gitlive/firebase/firestore/FieldPath; public final fun component2 ()Ldev/gitlive/firebase/firestore/WhereConstraint; public fun equals (Ljava/lang/Object;)Z @@ -217,27 +238,33 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { public final fun all ([Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter; public final fun and (Ldev/gitlive/firebase/firestore/Filter;Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter$And; public final fun any ([Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter; - public final fun contains (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun contains (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun containsAny (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun containsAny (Ljava/lang/String;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun equalTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun equalTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThan (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThan (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun greaterThanOrEqualTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun inArray (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun inArray (Ljava/lang/String;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThan (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThan (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun lessThanOrEqualTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notEqualTo (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notInArray (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; - public final fun notInArray (Ljava/lang/String;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun contains (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun contains (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun containsAny (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun containsAny (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun equalTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun equalTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; + public final fun greaterThan (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun greaterThan (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun greaterThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun greaterThanOrEqualTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun inArray (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun inArray (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNotNull (Ldev/gitlive/firebase/firestore/FieldPath;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNotNull (Ljava/lang/String;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNull (Ldev/gitlive/firebase/firestore/FieldPath;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun isNull (Ljava/lang/String;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThan (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThan (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThanOrEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun lessThanOrEqualTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notEqualTo (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notEqualTo (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notInArray (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; + public final fun notInArray (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Filter$WithConstraint; public final fun or (Ldev/gitlive/firebase/firestore/Filter;Ldev/gitlive/firebase/firestore/Filter;)Ldev/gitlive/firebase/firestore/Filter$Or; + public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V } public final class dev/gitlive/firebase/firestore/FirebaseFirestore { @@ -424,9 +451,15 @@ public final class dev/gitlive/firebase/firestore/MemoryGarbageCollectorSettings public class dev/gitlive/firebase/firestore/Query { public static final field Companion Ldev/gitlive/firebase/firestore/Query$Companion; public final fun endAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun endAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun endBefore ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endBefore$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBeforeWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun endBeforeWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun get (Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun get$default (Ldev/gitlive/firebase/firestore/Query;Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getSnapshots ()Lkotlinx/coroutines/flow/Flow; @@ -438,9 +471,15 @@ public class dev/gitlive/firebase/firestore/Query { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/Query;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public final fun startAfter (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAfter ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAfter$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfterWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAfterWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public static synthetic fun startAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun where (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; } @@ -565,8 +604,12 @@ public final class dev/gitlive/firebase/firestore/Transaction { public final fun updateEncodedFieldsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldPathsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public static synthetic fun updateFieldsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -576,117 +619,102 @@ public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint { } public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContains : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContainsAny : dev/gitlive/firebase/firestore/WhereConstraint$ForArray { + public fun (Ljava/util/List;)V public final fun component1 ()Ljava/util/List; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValues ()Ljava/util/List; public fun getValues ()Ljava/util/List; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$EqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$ForArray : dev/gitlive/firebase/firestore/WhereConstraint { - public abstract fun getSafeValues ()Ljava/util/List; public abstract fun getValues ()Ljava/util/List; } -public final class dev/gitlive/firebase/firestore/WhereConstraint$ForArray$DefaultImpls { - public static fun getSafeValues (Ldev/gitlive/firebase/firestore/WhereConstraint$ForArray;)Ljava/util/List; -} - public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject : dev/gitlive/firebase/firestore/WhereConstraint { - public abstract fun getSafeValue ()Ljava/lang/Object; public abstract fun getValue ()Ljava/lang/Object; } -public final class dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject$DefaultImpls { - public static fun getSafeValue (Ldev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject;)Ljava/lang/Object; -} - public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$ForObject : dev/gitlive/firebase/firestore/WhereConstraint { - public abstract fun getSafeValue ()Ljava/lang/Object; public abstract fun getValue ()Ljava/lang/Object; } -public final class dev/gitlive/firebase/firestore/WhereConstraint$ForObject$DefaultImpls { - public static fun getSafeValue (Ldev/gitlive/firebase/firestore/WhereConstraint$ForObject;)Ljava/lang/Object; -} - public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThan : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThanOrEqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$InArray : dev/gitlive/firebase/firestore/WhereConstraint$ForArray { + public fun (Ljava/util/List;)V public final fun component1 ()Ljava/util/List; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValues ()Ljava/util/List; public fun getValues ()Ljava/util/List; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThan : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThanOrEqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$NotEqualTo : dev/gitlive/firebase/firestore/WhereConstraint$ForNullableObject { + public fun (Ljava/lang/Object;)V public final fun component1 ()Ljava/lang/Object; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValue ()Ljava/lang/Object; public fun getValue ()Ljava/lang/Object; public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class dev/gitlive/firebase/firestore/WhereConstraint$NotInArray : dev/gitlive/firebase/firestore/WhereConstraint$ForArray { + public fun (Ljava/util/List;)V public final fun component1 ()Ljava/util/List; public fun equals (Ljava/lang/Object;)Z - public fun getSafeValues ()Ljava/util/List; public fun getValues ()Ljava/util/List; public fun hashCode ()I public fun toString ()Ljava/lang/String; @@ -720,6 +748,10 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldPathWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; + public static synthetic fun updateFieldPathWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; + public static synthetic fun updateFieldWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt new file mode 100644 index 000000000..ba97efbd7 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt @@ -0,0 +1,13 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.EncodeSettings +import kotlinx.serialization.SerializationStrategy + +public data class EncodableValue(public val encoded: (EncodeSettings.Builder.() -> Unit) -> Any?) + +public inline fun T.encodable(): EncodableValue = EncodableValue { + encode(this, it) +} +public fun T.encodableWithStrategy(stategy: SerializationStrategy): EncodableValue = EncodableValue { + dev.gitlive.firebase.internal.encode(stategy, this, it) +} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt index 4ad37abea..3b3f33a55 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt @@ -48,185 +48,185 @@ public class FilterBuilder internal constructor() { public val String.isNull: Filter.WithConstraint get() = Filter.Field(this, WhereConstraint.EqualTo(null)) public inline infix fun String.equalTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.EqualTo(encode(value, buildSettings)) + WhereConstraint.EqualTo(encode(value, buildSettings)), ) public fun String.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)), ) public val FieldPath.isNull: Filter.WithConstraint get() = Filter.Path(this, WhereConstraint.EqualTo(null)) public inline infix fun FieldPath.equalTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.EqualTo(encode(value, buildSettings)) + WhereConstraint.EqualTo(encode(value, buildSettings)), ) public fun FieldPath.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)), ) public val String.isNotNull: Filter.WithConstraint get() = Filter.Field(this, WhereConstraint.NotEqualTo(null)) public inline infix fun String.notEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotEqualTo(encode(value, buildSettings)) + WhereConstraint.NotEqualTo(encode(value, buildSettings)), ) public fun String.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)), ) public val FieldPath.isNotNull: Filter.WithConstraint get() = Filter.Path(this, WhereConstraint.NotEqualTo(null)) public inline infix fun FieldPath.notEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotEqualTo(encode(value, buildSettings)) + WhereConstraint.NotEqualTo(encode(value, buildSettings)), ) public fun FieldPath.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)), ) public inline infix fun String.lessThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(encode(value, buildSettings)!!) + WhereConstraint.LessThan(encode(value, buildSettings)!!), ) public fun String.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun FieldPath.lessThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(encode(value, buildSettings)!!) + WhereConstraint.LessThan(encode(value, buildSettings)!!), ) public fun FieldPath.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.greaterThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(encode(value, buildSettings)!!) + WhereConstraint.GreaterThan(encode(value, buildSettings)!!), ) public fun String.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun FieldPath.greaterThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(encode(value, buildSettings)!!) + WhereConstraint.GreaterThan(encode(value, buildSettings)!!), ) public fun FieldPath.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!) + WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!), ) public fun String.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun FieldPath.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!) + WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!), ) public fun FieldPath.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!) + WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!), ) public fun String.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun FieldPath.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!) + WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!), ) public fun FieldPath.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.contains(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(encode(value, buildSettings)!!) + WhereConstraint.ArrayContains(encode(value, buildSettings)!!), ) public fun String.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun FieldPath.contains(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(encode(value, buildSettings)!!) + WhereConstraint.ArrayContains(encode(value, buildSettings)!!), ) public fun FieldPath.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.containsAny(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContainsAny(values.map { encode(it, buildSettings)!! }) + WhereConstraint.ArrayContainsAny(values.map { encode(it, buildSettings)!! }), ) public fun String.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContainsAny(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }), ) public inline infix fun FieldPath.containsAny(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContainsAny(values.map { encode(it, buildSettings)!! }) + WhereConstraint.ArrayContainsAny(values.map { encode(it, buildSettings)!! }), ) public fun FieldPath.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContainsAny(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }), ) public inline infix fun String.inArray(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.InArray(values.map { encode(it, buildSettings)!! }) + WhereConstraint.InArray(values.map { encode(it, buildSettings)!! }), ) public fun String.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.InArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }), ) public inline infix fun FieldPath.inArray(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.InArray(values.map { encode(it, buildSettings)!! }) + WhereConstraint.InArray(values.map { encode(it, buildSettings)!! }), ) public fun FieldPath.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.InArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }), ) public inline infix fun String.notInArray(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotInArray(values.map { encode(it, buildSettings)!! }) + WhereConstraint.NotInArray(values.map { encode(it, buildSettings)!! }), ) public fun String.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotInArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }), ) public inline infix fun FieldPath.notInArray(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotInArray(values.map { encode(it, buildSettings)!! }) + WhereConstraint.NotInArray(values.map { encode(it, buildSettings)!! }), ) public fun FieldPath.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotInArray(values.map {dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }) + WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, buildSettings)!! }), ) public infix fun Filter.and(right: Filter): Filter.And { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 795c481b1..98f744214 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -190,10 +190,24 @@ public data class Transaction internal constructor(internal val nativeWrapper: N public inline fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncoded(documentRef, encodeAsObject(strategy, data, buildSettings)) @JvmName("updateFields") - public inline fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncodedFieldsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = update( + documentRef, + *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), + buildSettings = buildSettings, + ) + + @JvmName("updateFieldsWithEncodableValue") + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncodedFieldsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) @JvmName("updateFieldPaths") - public inline fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncodedFieldPathsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = update( + documentRef, + *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), + buildSettings = buildSettings, + ) + + @JvmName("updateFieldPathsWithEncodableValue") + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncodedFieldPathsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, encodedData)) @@ -229,14 +243,26 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun orderBy(field: FieldPath, direction: Direction = Direction.ASCENDING): Query = Query(nativeQuery.orderBy(field.encoded, direction)) public fun startAfter(document: DocumentSnapshot): Query = Query(nativeQuery.startAfter(document.native)) - public fun startAfter(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAfter(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) + public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAfter(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) + + @JvmName("startAfterWithEncodableValue") + public fun startAfter(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAfter(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) public fun startAt(document: DocumentSnapshot): Query = Query(nativeQuery.startAt(document.native)) - public fun startAt(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAt(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) + public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAt(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) + + @JvmName("startAtWithEncodableValue") + public fun startAt(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAt(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) public fun endBefore(document: DocumentSnapshot): Query = Query(nativeQuery.endBefore(document.native)) - public fun endBefore(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endBefore(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) + public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endBefore(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) + + @JvmName("endBeforeWithEncodableValue") + public fun endBefore(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endBefore(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) public fun endAt(document: DocumentSnapshot): Query = Query(nativeQuery.endAt(document.native)) - public fun endAt(vararg fieldValues: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endAt(*(fieldValues.map { encode(it, buildSettings)!! }.toTypedArray()))) + public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endAt(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) + + @JvmName("endAtWithEncodableValue") + public fun endAt(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endAt(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) } @Deprecated("Deprecated in favor of using a [FilterBuilder]", replaceWith = ReplaceWith("where { field equalTo equalTo }", "dev.gitlive.firebase.firestore")) @@ -361,10 +387,24 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na updateEncoded(documentRef, encodeAsObject(strategy, data, buildSettings)) @JvmName("updateField") - public inline fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncodedFieldsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = update( + documentRef, + *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), + buildSettings = buildSettings, + ) + + @JvmName("updateFieldWithEncodableValues") + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncodedFieldsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) @JvmName("updateFieldPath") - public inline fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncodedFieldPathsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = update( + documentRef, + *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), + buildSettings = buildSettings, + ) + + @JvmName("updateFieldPathWithEncodableValues") + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncodedFieldPathsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedData)) @@ -512,7 +552,13 @@ public data class DocumentReference internal constructor(internal val native: Na } @JvmName("updateFields") - public suspend inline fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}) { + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = update( + *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), + buildSettings = buildSettings, + ) + + @JvmName("updateFieldsWithEncodableValues") + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}) { updateEncodedFieldsAndValues( encodeFieldAndValue( fieldsAndValues, @@ -527,7 +573,13 @@ public data class DocumentReference internal constructor(internal val native: Na } @JvmName("updateFieldPaths") - public suspend inline fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}) { + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = update( + *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), + buildSettings = buildSettings, + ) + + @JvmName("updateFieldPathsWithEncodableValue") + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}) { updateEncodedFieldPathsAndValues( encodeFieldAndValue( fieldsAndValues, diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt index 766836a76..7a225b0f4 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt @@ -6,28 +6,28 @@ import kotlin.jvm.JvmName // ** Helper method to perform an update operation. */ @JvmName("performUpdateFields") @PublishedApi -internal inline fun encodeFieldAndValue( - fieldsAndValues: Array>, +internal fun encodeFieldAndValue( + fieldsAndValues: Array>, buildSettings: EncodeSettings.Builder.() -> Unit, -): List>? = encodeFieldAndValue(fieldsAndValues, encodeField = { it }, encodeValue = { encode(it, buildSettings) }) +): List>? = encodeFieldAndValue(fieldsAndValues, encodeField = { it }, buildSettings) /** Helper method to perform an update operation. */ @JvmName("performUpdateFieldPaths") @PublishedApi -internal inline fun encodeFieldAndValue( - fieldsAndValues: Array>, +internal fun encodeFieldAndValue( + fieldsAndValues: Array>, buildSettings: EncodeSettings.Builder.() -> Unit, -): List>? = encodeFieldAndValue(fieldsAndValues, { it.encoded }, { encode(it, buildSettings) }) +): List>? = encodeFieldAndValue(fieldsAndValues, { it.encoded }, buildSettings) /** Helper method to perform an update operation in Android and JS. */ @PublishedApi internal inline fun encodeFieldAndValue( - fieldsAndValues: Array>, + fieldsAndValues: Array>, encodeField: (T) -> K, - encodeValue: (Any?) -> Any?, + noinline buildSettings: EncodeSettings.Builder.() -> Unit, ): List>? = fieldsAndValues.takeUnless { fieldsAndValues.isEmpty() } - ?.map { (field, value) -> encodeField(field) to value?.let { encodeValue(it) } } + ?.map { (field, value) -> encodeField(field) to value.encoded(buildSettings) } internal fun List>.performUpdate( update: (K, Any?, Array) -> R, diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt index d6625b1b9..54375c9b5 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -12,7 +12,6 @@ import dev.gitlive.firebase.internal.decode import dev.gitlive.firebase.initialize import dev.gitlive.firebase.runBlockingTest import dev.gitlive.firebase.runTest -import dev.gitlive.firebase.withSerializer import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.delay @@ -67,7 +66,7 @@ class FirebaseFirestoreTest { @Serializable data class NestedObject( - val prop2: String + val prop2: String, ) companion object { @@ -730,7 +729,7 @@ class FirebaseFirestoreTest { // update data val updatedData = DataWithDocumentReference(documentRef2) getDocument().update( - FieldPath(DataWithDocumentReference::documentReference.name) to updatedData.documentReference.withSerializer(DocumentReferenceSerializer), + FieldPath(DataWithDocumentReference::documentReference.name) to updatedData.documentReference.encodableWithStrategy(DocumentReferenceSerializer), ) // verify update val updatedSavedData = getDocument().get().data(DataWithDocumentReference.serializer()) From 3fde0f5b15e94abe0b04d07ac641ce12abb81f13 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 2 Sep 2024 01:07:41 +0200 Subject: [PATCH 24/33] Improves DSL for updating firestore references --- .../api/android/firebase-firestore.api | 67 +++----- .../api/jvm/firebase-firestore.api | 67 +++----- .../internal/NativeDocumentReference.kt | 12 +- .../internal/NativeTransactionWrapper.kt | 23 ++- .../internal/NativeWriteBatchWrapper.kt | 23 ++- .../firebase/firestore/EncodableValue.kt | 13 -- .../firebase/firestore/FieldValueBuilder.kt | 25 +++ .../firestore/FieldsAndValuesBuilder.kt | 39 +++++ .../gitlive/firebase/firestore/firestore.kt | 161 ++++++++++-------- .../dev/gitlive/firebase/firestore/helpers.kt | 67 ++++---- .../firestore/internal/FieldAndValue.kt | 11 ++ .../internal/NativeDocumentReference.kt | 4 +- .../internal/NativeTransactionWrapper.kt | 4 +- .../internal/NativeWriteBatchWrapper.kt | 4 +- .../gitlive/firebase/firestore/firestore.kt | 9 +- .../internal/NativeDocumentReference.kt | 11 +- .../internal/NativeTransactionWrapper.kt | 16 +- .../internal/NativeWriteBatchWrapper.kt | 16 +- .../internal/NativeDocumentReference.kt | 23 +-- .../internal/NativeTransactionWrapper.kt | 25 ++- .../internal/NativeWriteBatchWrapper.kt | 25 ++- 21 files changed, 318 insertions(+), 327 deletions(-) delete mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt create mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt create mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt create mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldAndValue.kt diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index 9dea82602..acbd2f13e 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -68,20 +68,16 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/DocumentReference;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public fun toString ()Ljava/lang/String; + public final fun update (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateEncoded (Ldev/gitlive/firebase/internal/EncodedObject;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateEncodedFieldPathsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun updateEncodedFieldsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateFieldPathsWithEncodableValue ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateFieldsWithEncodableValues ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFieldsWithEncodableValues$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -135,21 +131,6 @@ public final class dev/gitlive/firebase/firestore/DoubleAsTimestampSerializer : public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/firestore/EncodableValue { - public fun (Lkotlin/jvm/functions/Function1;)V - public final fun component1 ()Lkotlin/jvm/functions/Function1; - public final fun copy (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/EncodableValue; - public static synthetic fun copy$default (Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/EncodableValue; - public fun equals (Ljava/lang/Object;)Z - public final fun getEncoded ()Lkotlin/jvm/functions/Function1; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class dev/gitlive/firebase/firestore/EncodableValueKt { - public static final fun encodableWithStrategy (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ldev/gitlive/firebase/firestore/EncodableValue; -} - public final class dev/gitlive/firebase/firestore/FieldPath { public static final field Companion Ldev/gitlive/firebase/firestore/FieldPath$Companion; public fun ([Ljava/lang/String;)V @@ -180,6 +161,13 @@ public final class dev/gitlive/firebase/firestore/FieldValue$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class dev/gitlive/firebase/firestore/FieldValueBuilder { + public final fun addEncoded (Ljava/lang/Object;)V + public final fun addWithStrategy (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; + public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V +} + public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Ldev/gitlive/firebase/firestore/FieldValueSerializer; public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/gitlive/firebase/firestore/FieldValue; @@ -189,6 +177,15 @@ public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public final class dev/gitlive/firebase/firestore/FieldsAndValuesBuilder { + public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; + public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V + public final fun to (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + public final fun to (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + public final fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)V + public final fun toEncoded (Ljava/lang/String;Ljava/lang/Object;)V +} + public abstract class dev/gitlive/firebase/firestore/Filter { } @@ -360,12 +357,6 @@ public final class dev/gitlive/firebase/firestore/GeoPointSerializer : kotlinx/s public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/firestore/HelpersKt { - public static final fun encodeFieldAndValue ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public static final fun performUpdateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public static final fun performUpdateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ljava/util/List; -} - public abstract interface class dev/gitlive/firebase/firestore/LocalCacheSettings { } @@ -451,15 +442,13 @@ public final class dev/gitlive/firebase/firestore/MemoryGarbageCollectorSettings public class dev/gitlive/firebase/firestore/Query { public static final field Companion Ldev/gitlive/firebase/firestore/Query$Companion; public final fun endAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun endAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun endAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun endBefore$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun endBeforeWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endBeforeWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun get (Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun get$default (Ldev/gitlive/firebase/firestore/Query;Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getSnapshots ()Lkotlinx/coroutines/flow/Flow; @@ -471,15 +460,13 @@ public class dev/gitlive/firebase/firestore/Query { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/Query;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public final fun startAfter (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun startAfter$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAfterWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAfterWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun startAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun where (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; } @@ -595,21 +582,16 @@ public final class dev/gitlive/firebase/firestore/Transaction { public fun toString ()Ljava/lang/String; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateEncodedFieldPathsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateEncodedFieldsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFieldPathsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFieldsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFieldsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -738,6 +720,7 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun set$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;[Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun setEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;Ldev/gitlive/firebase/firestore/internal/SetOptions;)Ldev/gitlive/firebase/firestore/WriteBatch; public fun toString ()Ljava/lang/String; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; @@ -748,10 +731,6 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateFieldPathWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateFieldPathWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateFieldWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateFieldWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index ccf423cda..1a5f56fdb 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -68,20 +68,16 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/DocumentReference;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public fun toString ()Ljava/lang/String; + public final fun update (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateEncoded (Ldev/gitlive/firebase/internal/EncodedObject;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateEncodedFieldPathsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun updateEncodedFieldsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateFieldPathsWithEncodableValue ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateFieldsWithEncodableValues ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFieldsWithEncodableValues$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -135,21 +131,6 @@ public final class dev/gitlive/firebase/firestore/DoubleAsTimestampSerializer : public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/firestore/EncodableValue { - public fun (Lkotlin/jvm/functions/Function1;)V - public final fun component1 ()Lkotlin/jvm/functions/Function1; - public final fun copy (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/EncodableValue; - public static synthetic fun copy$default (Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/EncodableValue; - public fun equals (Ljava/lang/Object;)Z - public final fun getEncoded ()Lkotlin/jvm/functions/Function1; - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public final class dev/gitlive/firebase/firestore/EncodableValueKt { - public static final fun encodableWithStrategy (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ldev/gitlive/firebase/firestore/EncodableValue; -} - public final class dev/gitlive/firebase/firestore/FieldPath { public static final field Companion Ldev/gitlive/firebase/firestore/FieldPath$Companion; public fun ([Ljava/lang/String;)V @@ -180,6 +161,13 @@ public final class dev/gitlive/firebase/firestore/FieldValue$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class dev/gitlive/firebase/firestore/FieldValueBuilder { + public final fun addEncoded (Ljava/lang/Object;)V + public final fun addWithStrategy (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; + public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V +} + public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Ldev/gitlive/firebase/firestore/FieldValueSerializer; public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/gitlive/firebase/firestore/FieldValue; @@ -189,6 +177,15 @@ public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public final class dev/gitlive/firebase/firestore/FieldsAndValuesBuilder { + public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; + public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V + public final fun to (Ldev/gitlive/firebase/firestore/FieldPath;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + public final fun to (Ljava/lang/String;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + public final fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)V + public final fun toEncoded (Ljava/lang/String;Ljava/lang/Object;)V +} + public abstract class dev/gitlive/firebase/firestore/Filter { } @@ -360,12 +357,6 @@ public final class dev/gitlive/firebase/firestore/GeoPointSerializer : kotlinx/s public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/firestore/HelpersKt { - public static final fun encodeFieldAndValue ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public static final fun performUpdateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ljava/util/List; - public static final fun performUpdateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ljava/util/List; -} - public abstract interface class dev/gitlive/firebase/firestore/LocalCacheSettings { } @@ -451,15 +442,13 @@ public final class dev/gitlive/firebase/firestore/MemoryGarbageCollectorSettings public class dev/gitlive/firebase/firestore/Query { public static final field Companion Ldev/gitlive/firebase/firestore/Query$Companion; public final fun endAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun endAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun endAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun endBefore$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun endBeforeWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endBeforeWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun get (Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun get$default (Ldev/gitlive/firebase/firestore/Query;Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getSnapshots ()Lkotlinx/coroutines/flow/Flow; @@ -471,15 +460,13 @@ public class dev/gitlive/firebase/firestore/Query { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/Query;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public final fun startAfter (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun startAfter$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAfterWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAfterWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; public static synthetic fun startAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAtWithEncodableValue ([Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAtWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Query;[Ldev/gitlive/firebase/firestore/EncodableValue;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun where (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; } @@ -595,21 +582,16 @@ public final class dev/gitlive/firebase/firestore/Transaction { public fun toString ()Ljava/lang/String; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateEncodedFieldPathsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateEncodedFieldsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFieldPathsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFieldPathsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFieldsWithEncodableValue (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFieldsWithEncodableValue$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -738,6 +720,7 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun set$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;[Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun setEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;Ldev/gitlive/firebase/firestore/internal/SetOptions;)Ldev/gitlive/firebase/firestore/WriteBatch; public fun toString ()Ljava/lang/String; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; @@ -748,10 +731,6 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateFieldPathWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateFieldPathWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateFieldWithEncodableValues (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateFieldWithEncodableValues$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt index cb91ffd74..2cc2047a0 100644 --- a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt +++ b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt @@ -2,7 +2,6 @@ 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 @@ -44,19 +43,12 @@ internal actual class NativeDocumentReference actual constructor(actual val nati android.update(encodedData.android).await() } - actual suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List>) { + actual suspend fun updateEncoded(encodedFieldsAndValues: List) { encodedFieldsAndValues.takeUnless { encodedFieldsAndValues.isEmpty() }?.let { - android.update(encodedFieldsAndValues.toMap()) + encodedFieldsAndValues.performUpdate(android::update, android::update) }?.await() } - actual suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List>) { - encodedFieldsAndValues.takeUnless { encodedFieldsAndValues.isEmpty() } - ?.performUpdate { field, value, moreFieldsAndValues -> - android.update(field, value, *moreFieldsAndValues) - }?.await() - } - actual suspend fun delete() { android.delete().await() } diff --git a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt index 4b8219703..ea20d3f33 100644 --- a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt +++ b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt @@ -1,7 +1,6 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeTransaction import dev.gitlive.firebase.firestore.android import dev.gitlive.firebase.firestore.performUpdate @@ -23,19 +22,17 @@ internal actual class NativeTransactionWrapper internal actual constructor(actua actual fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject) = native.update(documentRef.android, encodedData.android).let { this } - actual fun updateEncodedFieldsAndValues( + actual fun updateEncoded( documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ) = encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - native.update(documentRef.android, field, value, *moreFieldsAndValues) - }.let { this } - - actual fun updateEncodedFieldPathsAndValues( - documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ) = encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - native.update(documentRef.android, field, value, *moreFieldsAndValues) - }.let { this } + encodedFieldsAndValues: List, + ) = encodedFieldsAndValues.performUpdate( + updateAsField = { field, value, moreFieldsAndValues -> + native.update(documentRef.android, field, value, *moreFieldsAndValues) + }, + updateAsFieldPath = { fieldPath, value, moreFieldsAndValues -> + native.update(documentRef.android, fieldPath, value, *moreFieldsAndValues) + }, + ).let { this } actual fun delete(documentRef: DocumentReference) = native.delete(documentRef.android).let { this } diff --git a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt index 9aa34f700..1a3bd69b9 100644 --- a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt +++ b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt @@ -1,7 +1,6 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeWriteBatch import dev.gitlive.firebase.firestore.android import dev.gitlive.firebase.firestore.performUpdate @@ -25,19 +24,17 @@ internal actual class NativeWriteBatchWrapper internal actual constructor(actual actual fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject) = native.update(documentRef.android, encodedData.android).let { this } - actual fun updateEncodedFieldsAndValues( + actual fun updateEncoded( documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ) = encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - native.update(documentRef.android, field, value, *moreFieldsAndValues) - }.let { this } - - actual fun updateEncodedFieldPathsAndValues( - documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ) = encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - native.update(documentRef.android, field, value, *moreFieldsAndValues) - }.let { this } + encodedFieldsAndValues: List, + ) = encodedFieldsAndValues.performUpdate( + updateAsField = { field, value, moreFieldsAndValues -> + native.update(documentRef.android, field, value, *moreFieldsAndValues) + }, + updateAsFieldPath = { fieldPath, value, moreFieldsAndValues -> + native.update(documentRef.android, fieldPath, value, *moreFieldsAndValues) + }, + ).let { this } actual fun delete(documentRef: DocumentReference) = native.delete(documentRef.android).let { this } diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt deleted file mode 100644 index ba97efbd7..000000000 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/EncodableValue.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.gitlive.firebase.firestore - -import dev.gitlive.firebase.EncodeSettings -import kotlinx.serialization.SerializationStrategy - -public data class EncodableValue(public val encoded: (EncodeSettings.Builder.() -> Unit) -> Any?) - -public inline fun T.encodable(): EncodableValue = EncodableValue { - encode(this, it) -} -public fun T.encodableWithStrategy(stategy: SerializationStrategy): EncodableValue = EncodableValue { - dev.gitlive.firebase.internal.encode(stategy, this, it) -} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt new file mode 100644 index 000000000..53d5a0d13 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt @@ -0,0 +1,25 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.EncodeSettings +import kotlinx.serialization.SerializationStrategy + +public class FieldValueBuilder internal constructor() { + + internal val fieldValues: MutableList = mutableListOf() + public var buildSettings: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } + + public inline fun add(value: T) { + addEncoded(encode(value, buildSettings)!!) + } + + public fun addWithStrategy(strategy: SerializationStrategy, value: T) { + addEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + } + + @PublishedApi + internal fun addEncoded(encodedValue: Any) { + fieldValues += encodedValue + } +} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt new file mode 100644 index 000000000..aba64b228 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt @@ -0,0 +1,39 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.firestore.internal.FieldAndValue +import kotlinx.serialization.SerializationStrategy + +public class FieldsAndValuesBuilder internal constructor() { + + internal val fieldAndValues: MutableList = mutableListOf() + public var buildSettings: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } + + public inline infix fun String.to(value: T) { + toEncoded(encode(value, buildSettings)) + } + + public inline infix fun FieldPath.to(value: T) { + toEncoded(encode(value, buildSettings)) + } + + public fun String.to(strategy: SerializationStrategy, value: T) { + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + } + + public fun FieldPath.to(strategy: SerializationStrategy, value: T) { + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + } + + @PublishedApi + internal fun String.toEncoded(encodedValue: Any?) { + fieldAndValues += FieldAndValue.WithStringField(this, encodedValue) + } + + @PublishedApi + internal fun FieldPath.toEncoded(encodedValue: Any?) { + fieldAndValues += FieldAndValue.WithFieldPath(this, encodedValue) + } +} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 98f744214..bde643033 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -10,6 +10,7 @@ import dev.gitlive.firebase.internal.EncodedObject import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.FirebaseApp import dev.gitlive.firebase.FirebaseException +import dev.gitlive.firebase.firestore.internal.FieldAndValue import dev.gitlive.firebase.firestore.internal.NativeCollectionReferenceWrapper import dev.gitlive.firebase.firestore.internal.NativeDocumentReference import dev.gitlive.firebase.firestore.internal.NativeDocumentSnapshotWrapper @@ -192,32 +193,33 @@ public data class Transaction internal constructor(internal val nativeWrapper: N @JvmName("updateFields") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = update( documentRef, - *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), - buildSettings = buildSettings, + fieldsAndValuesBuilder = { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + }, ) - @JvmName("updateFieldsWithEncodableValue") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncodedFieldsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) - @JvmName("updateFieldPaths") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = update( documentRef, - *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), - buildSettings = buildSettings, + fieldsAndValuesBuilder = { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + }, ) - @JvmName("updateFieldPathsWithEncodableValue") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncodedFieldPathsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) + public fun update( + documentRef: DocumentReference, + fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, + ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, encodedData)) - @PublishedApi - internal fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): Transaction = Transaction(nativeWrapper.updateEncodedFieldsAndValues(documentRef, encodedFieldsAndValues)) - - @PublishedApi - internal fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): Transaction = Transaction(nativeWrapper.updateEncodedFieldPathsAndValues(documentRef, encodedFieldsAndValues)) - public fun delete(documentRef: DocumentReference): Transaction = Transaction(nativeWrapper.delete(documentRef)) public suspend fun get(documentRef: DocumentReference): DocumentSnapshot = DocumentSnapshot(nativeWrapper.get(documentRef)) } @@ -243,26 +245,48 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun orderBy(field: FieldPath, direction: Direction = Direction.ASCENDING): Query = Query(nativeQuery.orderBy(field.encoded, direction)) public fun startAfter(document: DocumentSnapshot): Query = Query(nativeQuery.startAfter(document.native)) - public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAfter(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) + public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAfter( + builder = { + this.buildSettings = buildSettings + fieldValues.forEach { + add(it) + } + }, + ) + public fun startAfter(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAfter(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) - @JvmName("startAfterWithEncodableValue") - public fun startAfter(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAfter(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) public fun startAt(document: DocumentSnapshot): Query = Query(nativeQuery.startAt(document.native)) - public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAt(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) - - @JvmName("startAtWithEncodableValue") - public fun startAt(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.startAt(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) + public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAt( + builder = { + this.buildSettings = buildSettings + fieldValues.forEach { + add(it) + } + }, + ) + public fun startAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun endBefore(document: DocumentSnapshot): Query = Query(nativeQuery.endBefore(document.native)) - public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endBefore(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) + public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endBefore( + builder = { + this.buildSettings = buildSettings + fieldValues.forEach { + add(it) + } + }, + ) + public fun endBefore(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endBefore(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) - @JvmName("endBeforeWithEncodableValue") - public fun endBefore(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endBefore(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) public fun endAt(document: DocumentSnapshot): Query = Query(nativeQuery.endAt(document.native)) - public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endAt(*fieldValues.map { it.encodable() }.toTypedArray(), buildSettings = buildSettings) - - @JvmName("endAtWithEncodableValue") - public fun endAt(vararg fieldValues: EncodableValue, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = Query(nativeQuery.endAt(*(fieldValues.map { it.encoded(buildSettings)!! }.toTypedArray()))) + public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endAt( + builder = { + this.buildSettings = buildSettings + fieldValues.forEach { + add(it) + } + }, + ) + public fun endAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) } @Deprecated("Deprecated in favor of using a [FilterBuilder]", replaceWith = ReplaceWith("where { field equalTo equalTo }", "dev.gitlive.firebase.firestore")) @@ -389,31 +413,41 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na @JvmName("updateField") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = update( documentRef, - *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), - buildSettings = buildSettings, + fieldAndValuesBuilder = { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + }, ) - @JvmName("updateFieldWithEncodableValues") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncodedFieldsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) - @JvmName("updateFieldPath") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = update( documentRef, - *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), - buildSettings = buildSettings, + fieldAndValuesBuilder = { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (path, value) -> + path to value + } + }, ) - @JvmName("updateFieldPathWithEncodableValues") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncodedFieldPathsAndValues(documentRef, encodeFieldAndValue(fieldsAndValues, buildSettings).orEmpty()) + public fun update( + documentRef: DocumentReference, + fieldAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, + ): WriteBatch = updateEncodedFieldPathsAndValues( + documentRef, + FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, + ) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedData)) @PublishedApi - internal fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): WriteBatch = WriteBatch(nativeWrapper.updateEncodedFieldsAndValues(documentRef, encodedFieldsAndValues)) + internal fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedFieldsAndValues)) @PublishedApi - internal fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): WriteBatch = WriteBatch(nativeWrapper.updateEncodedFieldPathsAndValues(documentRef, encodedFieldsAndValues)) + internal fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedFieldsAndValues)) public fun delete(documentRef: DocumentReference): WriteBatch = WriteBatch(nativeWrapper.delete(documentRef)) public suspend fun commit() { @@ -553,44 +587,33 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFields") public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = update( - *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), - buildSettings = buildSettings, + fieldsAndValuesBuilder = { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + }, ) - @JvmName("updateFieldsWithEncodableValues") - public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}) { - updateEncodedFieldsAndValues( - encodeFieldAndValue( - fieldsAndValues, - buildSettings, - ).orEmpty(), - ) - } - - @PublishedApi - internal suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List>) { - native.updateEncodedFieldsAndValues(encodedFieldsAndValues) - } - @JvmName("updateFieldPaths") public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = update( - *fieldsAndValues.map { (key, value) -> key to value.encodable() }.toTypedArray(), - buildSettings = buildSettings, + fieldsAndValuesBuilder = { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (fieldPath, value) -> + fieldPath to value + } + }, ) - @JvmName("updateFieldPathsWithEncodableValue") - public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}) { - updateEncodedFieldPathsAndValues( - encodeFieldAndValue( - fieldsAndValues, - buildSettings, - ).orEmpty(), - ) + public suspend fun update( + fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, + ) { + updateEncodedFieldPathsAndValues(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) } @PublishedApi - internal suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List>) { - native.updateEncodedFieldPathsAndValues(encodedFieldsAndValues) + internal suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List) { + native.updateEncoded(encodedFieldsAndValues) } public suspend fun delete() { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt index 7a225b0f4..7247ca002 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/helpers.kt @@ -1,38 +1,39 @@ package dev.gitlive.firebase.firestore -import dev.gitlive.firebase.EncodeSettings -import kotlin.jvm.JvmName +import dev.gitlive.firebase.firestore.internal.FieldAndValue -// ** Helper method to perform an update operation. */ -@JvmName("performUpdateFields") -@PublishedApi -internal fun encodeFieldAndValue( - fieldsAndValues: Array>, - buildSettings: EncodeSettings.Builder.() -> Unit, -): List>? = encodeFieldAndValue(fieldsAndValues, encodeField = { it }, buildSettings) +internal fun List.performUpdate( + updateAsField: (String, Any?, Array) -> R, + updateAsFieldPath: (EncodedFieldPath, Any?, Array) -> R, +): R { + val first = first() + val remaining = drop(1).flatMap { fieldAndValue -> + listOf( + when (fieldAndValue) { + is FieldAndValue.WithFieldPath -> fieldAndValue.path.encoded + is FieldAndValue.WithStringField -> fieldAndValue.field + }, + fieldAndValue.value, + ) + } + return when (first) { + is FieldAndValue.WithFieldPath -> updateAsFieldPath( + first.path.encoded, + first.value, + remaining.toTypedArray(), + ) -/** Helper method to perform an update operation. */ -@JvmName("performUpdateFieldPaths") -@PublishedApi -internal fun encodeFieldAndValue( - fieldsAndValues: Array>, - buildSettings: EncodeSettings.Builder.() -> Unit, -): List>? = encodeFieldAndValue(fieldsAndValues, { it.encoded }, buildSettings) + is FieldAndValue.WithStringField -> updateAsField( + first.field, + first.value, + remaining.toTypedArray(), + ) + } +} -/** Helper method to perform an update operation in Android and JS. */ -@PublishedApi -internal inline fun encodeFieldAndValue( - fieldsAndValues: Array>, - encodeField: (T) -> K, - noinline buildSettings: EncodeSettings.Builder.() -> Unit, -): List>? = - fieldsAndValues.takeUnless { fieldsAndValues.isEmpty() } - ?.map { (field, value) -> encodeField(field) to value.encoded(buildSettings) } - -internal fun List>.performUpdate( - update: (K, Any?, Array) -> R, -) = update( - this[0].first, - this[0].second, - this.drop(1).flatMap { (field, value) -> listOf(field, value) }.toTypedArray(), -) +internal fun List.toEncodedMap(): Map = associate { fieldAndValue -> + when (fieldAndValue) { + is FieldAndValue.WithStringField -> fieldAndValue.field to fieldAndValue.value + is FieldAndValue.WithFieldPath -> fieldAndValue.path.encoded to fieldAndValue.value + } +} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldAndValue.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldAndValue.kt new file mode 100644 index 000000000..c4d5beeb4 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldAndValue.kt @@ -0,0 +1,11 @@ +package dev.gitlive.firebase.firestore.internal + +import dev.gitlive.firebase.firestore.FieldPath + +internal sealed class FieldAndValue { + + abstract val value: Any? + + data class WithStringField(val field: String, override val value: Any?) : FieldAndValue() + data class WithFieldPath(val path: FieldPath, override val value: Any?) : FieldAndValue() +} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt index baa706419..7cf376cf8 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt @@ -1,6 +1,5 @@ package dev.gitlive.firebase.firestore.internal -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeCollectionReference import dev.gitlive.firebase.firestore.NativeDocumentReferenceType import dev.gitlive.firebase.firestore.NativeDocumentSnapshot @@ -20,7 +19,6 @@ internal expect class NativeDocumentReference(nativeValue: NativeDocumentReferen suspend fun get(source: Source = Source.DEFAULT): NativeDocumentSnapshot suspend fun setEncoded(encodedData: EncodedObject, setOptions: SetOptions) suspend fun updateEncoded(encodedData: EncodedObject) - suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List>) - suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List>) + suspend fun updateEncoded(encodedFieldsAndValues: List) suspend fun delete() } diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt index 6bb72eedf..8a4df4971 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt @@ -1,7 +1,6 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeTransaction import dev.gitlive.firebase.internal.EncodedObject @@ -11,8 +10,7 @@ internal expect class NativeTransactionWrapper internal constructor(native: Nati fun setEncoded(documentRef: DocumentReference, encodedData: EncodedObject, setOptions: SetOptions): NativeTransactionWrapper fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeTransactionWrapper - fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeTransactionWrapper - fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeTransactionWrapper + fun updateEncoded(documentRef: DocumentReference, encodedFieldsAndValues: List): NativeTransactionWrapper fun delete(documentRef: DocumentReference): NativeTransactionWrapper suspend fun get(documentRef: DocumentReference): NativeDocumentSnapshotWrapper } diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt index bea3d0071..fee11b836 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt @@ -1,7 +1,6 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeWriteBatch import dev.gitlive.firebase.internal.EncodedObject @@ -9,8 +8,7 @@ internal expect class NativeWriteBatchWrapper internal constructor(native: Nativ val native: NativeWriteBatch fun setEncoded(documentRef: DocumentReference, encodedData: EncodedObject, setOptions: SetOptions): NativeWriteBatchWrapper fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeWriteBatchWrapper - fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeWriteBatchWrapper - fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List>): NativeWriteBatchWrapper + fun updateEncoded(documentRef: DocumentReference, encodedFieldsAndValues: List): NativeWriteBatchWrapper fun delete(documentRef: DocumentReference): NativeWriteBatchWrapper suspend fun commit() } diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 54375c9b5..4c727df6a 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -728,9 +728,12 @@ class FirebaseFirestoreTest { // update data val updatedData = DataWithDocumentReference(documentRef2) - getDocument().update( - FieldPath(DataWithDocumentReference::documentReference.name) to updatedData.documentReference.encodableWithStrategy(DocumentReferenceSerializer), - ) + getDocument().update(fieldsAndValuesBuilder = { + FieldPath(DataWithDocumentReference::documentReference.name).to( + DocumentReferenceSerializer, + updatedData.documentReference, + ) + }) // verify update val updatedSavedData = getDocument().get().data(DataWithDocumentReference.serializer()) assertEquals(updatedData.documentReference.path, updatedSavedData.documentReference.path) diff --git a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt index 98856556b..4f2c72d14 100644 --- a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt +++ b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt @@ -1,10 +1,10 @@ package dev.gitlive.firebase.firestore.internal -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeDocumentReferenceType import dev.gitlive.firebase.firestore.Source import dev.gitlive.firebase.firestore.await import dev.gitlive.firebase.firestore.awaitResult +import dev.gitlive.firebase.firestore.toEncodedMap import dev.gitlive.firebase.firestore.toException import dev.gitlive.firebase.internal.EncodedObject import dev.gitlive.firebase.internal.ios @@ -55,14 +55,9 @@ internal actual class NativeDocumentReference actual constructor(actual val nati ios.updateData(encodedData.ios, it) } - actual suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List>) = + actual suspend fun updateEncoded(encodedFieldsAndValues: List) = await { - ios.updateData(encodedFieldsAndValues.toMap(), it) - } - - actual suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List>) = - await { - ios.updateData(encodedFieldsAndValues.toMap(), it) + ios.updateData(encodedFieldsAndValues.toEncodedMap(), it) } actual suspend fun delete() = await { ios.deleteDocumentWithCompletion(it) } diff --git a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt index a9fe0014d..4a95a6610 100644 --- a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt +++ b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt @@ -2,8 +2,8 @@ package dev.gitlive.firebase.firestore.internal import cocoapods.FirebaseFirestoreInternal.FIRTransaction import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.ios +import dev.gitlive.firebase.firestore.toEncodedMap import dev.gitlive.firebase.internal.EncodedObject import dev.gitlive.firebase.internal.ios @@ -22,19 +22,11 @@ internal actual class NativeTransactionWrapper actual constructor(actual val nat actual fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeTransactionWrapper = native.updateData(encodedData.ios, documentRef.ios).let { this } - actual fun updateEncodedFieldsAndValues( + actual fun updateEncoded( documentRef: DocumentReference, - encodedFieldsAndValues: List>, + encodedFieldsAndValues: List, ): NativeTransactionWrapper = native.updateData( - encodedFieldsAndValues.toMap(), - documentRef.ios, - ).let { this } - - actual fun updateEncodedFieldPathsAndValues( - documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ): NativeTransactionWrapper = native.updateData( - encodedFieldsAndValues.toMap(), + encodedFieldsAndValues.toEncodedMap(), documentRef.ios, ).let { this } diff --git a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt index f1551cecf..ef8899553 100644 --- a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt +++ b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt @@ -1,10 +1,10 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeWriteBatch import dev.gitlive.firebase.firestore.await import dev.gitlive.firebase.firestore.ios +import dev.gitlive.firebase.firestore.toEncodedMap import dev.gitlive.firebase.internal.EncodedObject import dev.gitlive.firebase.internal.ios @@ -23,19 +23,11 @@ internal actual class NativeWriteBatchWrapper actual constructor(actual val nati actual fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeWriteBatchWrapper = native.updateData(encodedData.ios, documentRef.ios).let { this } - actual fun updateEncodedFieldsAndValues( + actual fun updateEncoded( documentRef: DocumentReference, - encodedFieldsAndValues: List>, + encodedFieldsAndValues: List, ): NativeWriteBatchWrapper = native.updateData( - encodedFieldsAndValues.toMap(), - documentRef.ios, - ).let { this } - - actual fun updateEncodedFieldPathsAndValues( - documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ): NativeWriteBatchWrapper = native.updateData( - encodedFieldsAndValues.toMap(), + encodedFieldsAndValues.toEncodedMap(), documentRef.ios, ).let { this } diff --git a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt index 5065defa2..ac72e14af 100644 --- a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt +++ b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeDocumentReference.kt @@ -1,6 +1,5 @@ package dev.gitlive.firebase.firestore.internal -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeCollectionReference import dev.gitlive.firebase.firestore.NativeDocumentReferenceType import dev.gitlive.firebase.firestore.NativeDocumentSnapshot @@ -74,25 +73,21 @@ internal actual class NativeDocumentReference actual constructor(actual val nati ).await() } - actual suspend fun updateEncodedFieldsAndValues(encodedFieldsAndValues: List>) { + actual suspend fun updateEncoded(encodedFieldsAndValues: List) { rethrow { encodedFieldsAndValues.takeUnless { encodedFieldsAndValues.isEmpty() } - ?.performUpdate { field, value, moreFieldsAndValues -> - updateDoc(js, field, value, *moreFieldsAndValues) - } + ?.performUpdate( + updateAsField = { field, value, moreFieldsAndValues -> + updateDoc(js, field, value, *moreFieldsAndValues) + }, + updateAsFieldPath = { fieldPath, value, moreFieldsAndValues -> + updateDoc(js, fieldPath, value, *moreFieldsAndValues) + }, + ) ?.await() } } - actual suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List>) { - rethrow { - encodedFieldsAndValues.takeUnless { encodedFieldsAndValues.isEmpty() } - ?.performUpdate { field, value, moreFieldsAndValues -> - updateDoc(js, field, value, *moreFieldsAndValues) - }?.await() - } - } - actual suspend fun delete() = rethrow { deleteDoc(js).await() } override fun equals(other: Any?): Boolean = diff --git a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt index 59ba9896d..f12b9d637 100644 --- a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt +++ b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeTransactionWrapper.kt @@ -1,7 +1,6 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeTransaction import dev.gitlive.firebase.firestore.externals.Transaction import dev.gitlive.firebase.firestore.js @@ -29,22 +28,18 @@ internal actual class NativeTransactionWrapper internal actual constructor(actua actual fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeTransactionWrapper = rethrow { js.update(documentRef.js, encodedData.js) } .let { this } - actual fun updateEncodedFieldsAndValues( + actual fun updateEncoded( documentRef: DocumentReference, - encodedFieldsAndValues: List>, + encodedFieldsAndValues: List, ): NativeTransactionWrapper = rethrow { - encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - js.update(documentRef.js, field, value, *moreFieldsAndValues) - } - }.let { this } - - actual fun updateEncodedFieldPathsAndValues( - documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ): NativeTransactionWrapper = rethrow { - encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - js.update(documentRef.js, field, value, *moreFieldsAndValues) - } + encodedFieldsAndValues.performUpdate( + updateAsField = { field, value, moreFieldsAndValues -> + js.update(documentRef.js, field, value, *moreFieldsAndValues) + }, + updateAsFieldPath = { fieldPath, value, moreFieldsAndValues -> + js.update(documentRef.js, fieldPath, value, *moreFieldsAndValues) + }, + ) }.let { this } actual fun delete(documentRef: DocumentReference) = diff --git a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt index e97cc31ab..45515bdcc 100644 --- a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt +++ b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/internal/NativeWriteBatchWrapper.kt @@ -1,7 +1,6 @@ package dev.gitlive.firebase.firestore.internal import dev.gitlive.firebase.firestore.DocumentReference -import dev.gitlive.firebase.firestore.EncodedFieldPath import dev.gitlive.firebase.firestore.NativeWriteBatch import dev.gitlive.firebase.firestore.externals.WriteBatch import dev.gitlive.firebase.firestore.js @@ -26,22 +25,18 @@ internal actual class NativeWriteBatchWrapper internal actual constructor(actual actual fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): NativeWriteBatchWrapper = rethrow { js.update(documentRef.js, encodedData.js) } .let { this } - actual fun updateEncodedFieldsAndValues( + actual fun updateEncoded( documentRef: DocumentReference, - encodedFieldsAndValues: List>, + encodedFieldsAndValues: List, ): NativeWriteBatchWrapper = rethrow { - encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - js.update(documentRef.js, field, value, *moreFieldsAndValues) - } - }.let { this } - - actual fun updateEncodedFieldPathsAndValues( - documentRef: DocumentReference, - encodedFieldsAndValues: List>, - ): NativeWriteBatchWrapper = rethrow { - encodedFieldsAndValues.performUpdate { field, value, moreFieldsAndValues -> - js.update(documentRef.js, field, value, *moreFieldsAndValues) - } + encodedFieldsAndValues.performUpdate( + updateAsField = { field, value, moreFieldsAndValues -> + js.update(documentRef.js, field, value, *moreFieldsAndValues) + }, + updateAsFieldPath = { fieldPath, value, moreFieldsAndValues -> + js.update(documentRef.js, fieldPath, value, *moreFieldsAndValues) + }, + ) }.let { this } actual fun delete(documentRef: DocumentReference) = From 6e0a4de73422459c911bde7eb6d85a2a54cbb34c Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 2 Sep 2024 12:50:37 +0200 Subject: [PATCH 25/33] Slight api format change for readability --- .../api/android/firebase-firestore.api | 9 +- .../api/jvm/firebase-firestore.api | 9 +- .../gitlive/firebase/firestore/firestore.kt | 116 ++++++++---------- 3 files changed, 55 insertions(+), 79 deletions(-) diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index acbd2f13e..d02f12da2 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -68,16 +68,15 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/DocumentReference;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public fun toString ()Ljava/lang/String; - public final fun update (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateEncoded (Ldev/gitlive/firebase/internal/EncodedObject;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun updateEncodedFieldPathsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun updateWithBuilder (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -582,7 +581,6 @@ public final class dev/gitlive/firebase/firestore/Transaction { public fun toString ()Ljava/lang/String; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; - public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; @@ -592,6 +590,7 @@ public final class dev/gitlive/firebase/firestore/Transaction { public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -720,17 +719,15 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun set$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;[Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun setEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;Ldev/gitlive/firebase/firestore/internal/SetOptions;)Ldev/gitlive/firebase/firestore/WriteBatch; public fun toString ()Ljava/lang/String; - public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateEncodedFieldPathsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateEncodedFieldsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 1a5f56fdb..fee19cb9b 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -68,16 +68,15 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/DocumentReference;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public fun toString ()Ljava/lang/String; - public final fun update (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateEncoded (Ldev/gitlive/firebase/internal/EncodedObject;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun updateEncodedFieldPathsAndValues (Ljava/util/List;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public final fun updateWithBuilder (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -582,7 +581,6 @@ public final class dev/gitlive/firebase/firestore/Transaction { public fun toString ()Ljava/lang/String; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; - public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; @@ -592,6 +590,7 @@ public final class dev/gitlive/firebase/firestore/Transaction { public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -720,17 +719,15 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun set$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;[Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun setEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;Ldev/gitlive/firebase/firestore/internal/SetOptions;)Ldev/gitlive/firebase/firestore/WriteBatch; public fun toString ()Ljava/lang/String; - public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateEncodedFieldPathsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateEncodedFieldsAndValues (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/util/List;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index bde643033..7c149daac 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -10,7 +10,6 @@ import dev.gitlive.firebase.internal.EncodedObject import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.FirebaseApp import dev.gitlive.firebase.FirebaseException -import dev.gitlive.firebase.firestore.internal.FieldAndValue import dev.gitlive.firebase.firestore.internal.NativeCollectionReferenceWrapper import dev.gitlive.firebase.firestore.internal.NativeDocumentReference import dev.gitlive.firebase.firestore.internal.NativeDocumentSnapshotWrapper @@ -191,28 +190,26 @@ public data class Transaction internal constructor(internal val nativeWrapper: N public inline fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncoded(documentRef, encodeAsObject(strategy, data, buildSettings)) @JvmName("updateFields") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateWithBuilder( documentRef, - fieldsAndValuesBuilder = { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value - } - }, - ) + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + } @JvmName("updateFieldPaths") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateWithBuilder( documentRef, - fieldsAndValuesBuilder = { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value - } - }, - ) + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + } - public fun update( + public fun updateWithBuilder( documentRef: DocumentReference, fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) @@ -411,44 +408,38 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na updateEncoded(documentRef, encodeAsObject(strategy, data, buildSettings)) @JvmName("updateField") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateWithBuilder( documentRef, - fieldAndValuesBuilder = { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value - } - }, - ) + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + } @JvmName("updateFieldPath") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateWithBuilder( documentRef, - fieldAndValuesBuilder = { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (path, value) -> - path to value - } - }, - ) + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (path, value) -> + path to value + } + } - public fun update( + public fun updateWithBuilder( documentRef: DocumentReference, fieldAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, - ): WriteBatch = updateEncodedFieldPathsAndValues( - documentRef, - FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, + ): WriteBatch = WriteBatch( + nativeWrapper.updateEncoded( + documentRef, + FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, + ), ) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedData)) - @PublishedApi - internal fun updateEncodedFieldsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedFieldsAndValues)) - - @PublishedApi - internal fun updateEncodedFieldPathsAndValues(documentRef: DocumentReference, encodedFieldsAndValues: List): WriteBatch = WriteBatch(nativeWrapper.updateEncoded(documentRef, encodedFieldsAndValues)) - public fun delete(documentRef: DocumentReference): WriteBatch = WriteBatch(nativeWrapper.delete(documentRef)) public suspend fun commit() { nativeWrapper.commit() @@ -586,34 +577,25 @@ public data class DocumentReference internal constructor(internal val native: Na } @JvmName("updateFields") - public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = update( - fieldsAndValuesBuilder = { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value - } - }, - ) + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = updateWithBuilder { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } + } @JvmName("updateFieldPaths") - public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = update( - fieldsAndValuesBuilder = { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (fieldPath, value) -> - fieldPath to value - } - }, - ) + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = updateWithBuilder { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (fieldPath, value) -> + fieldPath to value + } + } - public suspend fun update( + public suspend fun updateWithBuilder( fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ) { - updateEncodedFieldPathsAndValues(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) - } - - @PublishedApi - internal suspend fun updateEncodedFieldPathsAndValues(encodedFieldsAndValues: List) { - native.updateEncoded(encodedFieldsAndValues) + native.updateEncoded(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) } public suspend fun delete() { From 66df979d2982a3479766715dafa7056d2400f530 Mon Sep 17 00:00:00 2001 From: Andrew Reed Date: Mon, 2 Sep 2024 14:11:22 +0100 Subject: [PATCH 26/33] Bumped version --- firebase-analytics/package.json | 4 ++-- firebase-app/package.json | 4 ++-- firebase-auth/package.json | 4 ++-- firebase-common/package.json | 2 +- firebase-config/package.json | 4 ++-- firebase-crashlytics/package.json | 4 ++-- firebase-database/package.json | 4 ++-- firebase-firestore/package.json | 4 ++-- firebase-functions/package.json | 4 ++-- firebase-installations/package.json | 4 ++-- firebase-messaging/package.json | 4 ++-- firebase-perf/package.json | 4 ++-- firebase-storage/package.json | 4 ++-- gradle.properties | 28 ++++++++++++++-------------- 14 files changed, 39 insertions(+), 39 deletions(-) diff --git a/firebase-analytics/package.json b/firebase-analytics/package.json index da4f8da37..047cf14c4 100644 --- a/firebase-analytics/package.json +++ b/firebase-analytics/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-analytics", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-analytics.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.6.10", "kotlinx-coroutines-core": "1.6.1-native-mt" diff --git a/firebase-app/package.json b/firebase-app/package.json index 9fceec0af..6bad942eb 100644 --- a/firebase-app/package.json +++ b/firebase-app/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-app", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-app.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-common": "2.0.0", + "@gitlive/firebase-common": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-auth/package.json b/firebase-auth/package.json index 23da53f91..5a2fe936b 100644 --- a/firebase-auth/package.json +++ b/firebase-auth/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-auth", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-auth.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-common/package.json b/firebase-common/package.json index ac1374d45..61f1c13d0 100644 --- a/firebase-common/package.json +++ b/firebase-common/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-common", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-common.js", "scripts": { diff --git a/firebase-config/package.json b/firebase-config/package.json index 69582d9fc..e8684ce16 100644 --- a/firebase-config/package.json +++ b/firebase-config/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-config", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-config.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-crashlytics/package.json b/firebase-crashlytics/package.json index 989eda9b0..77903f7d4 100644 --- a/firebase-crashlytics/package.json +++ b/firebase-crashlytics/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-crashlytics", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-crashlytics.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.6.10", "kotlinx-coroutines-core": "1.6.1-native-mt" diff --git a/firebase-database/package.json b/firebase-database/package.json index 228ba4282..7ed7fb0b2 100644 --- a/firebase-database/package.json +++ b/firebase-database/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-database", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-database.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-firestore/package.json b/firebase-firestore/package.json index 8efd2dd91..50c424548 100644 --- a/firebase-firestore/package.json +++ b/firebase-firestore/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-firestore", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-firestore.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-functions/package.json b/firebase-functions/package.json index ed25dbf4e..81ab98572 100644 --- a/firebase-functions/package.json +++ b/firebase-functions/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-functions", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-functions.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-installations/package.json b/firebase-installations/package.json index bd98df6a8..0f9ebb653 100644 --- a/firebase-installations/package.json +++ b/firebase-installations/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-installations", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-installations.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-messaging/package.json b/firebase-messaging/package.json index 057b92487..40ddedd6e 100644 --- a/firebase-messaging/package.json +++ b/firebase-messaging/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-messaging", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-messaging.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.8.20", "kotlinx-coroutines-core": "1.6.4" diff --git a/firebase-perf/package.json b/firebase-perf/package.json index cd6e77684..4efea2201 100644 --- a/firebase-perf/package.json +++ b/firebase-perf/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-perf", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-perf.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.6.10", "kotlinx-coroutines-core": "1.6.1-native-mt" diff --git a/firebase-storage/package.json b/firebase-storage/package.json index 07e46118b..8d6168aab 100644 --- a/firebase-storage/package.json +++ b/firebase-storage/package.json @@ -1,6 +1,6 @@ { "name": "@gitlive/firebase-storage", - "version": "2.0.0", + "version": "2.1.0", "description": "Wrapper around firebase for usage in Kotlin Multiplatform projects", "main": "firebase-storage.js", "scripts": { @@ -23,7 +23,7 @@ }, "homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk", "dependencies": { - "@gitlive/firebase-app": "2.0.0", + "@gitlive/firebase-app": "2.1.0", "firebase": "9.19.1", "kotlin": "1.6.10", "kotlinx-coroutines-core": "1.6.1-native-mt" diff --git a/gradle.properties b/gradle.properties index 01a9fd1fc..e15480737 100644 --- a/gradle.properties +++ b/gradle.properties @@ -70,17 +70,17 @@ firebase-perf.skipJsTests=false firebase-storage.skipJsTests=false # Versions: -firebase-analytics.version=2.0.0 -firebase-app.version=2.0.0 -firebase-auth.version=2.0.0 -firebase-common-internal.version=2.0.0 -firebase-common.version=2.0.0 -firebase-config.version=2.0.0 -firebase-crashlytics.version=2.0.0 -firebase-database.version=2.0.0 -firebase-firestore.version=2.0.0 -firebase-functions.version=2.0.0 -firebase-installations.version=2.0.0 -firebase-messaging.version=2.0.0 -firebase-perf.version=2.0.0 -firebase-storage.version=2.0.0 +firebase-analytics.version=2.1.0 +firebase-app.version=2.1.0 +firebase-auth.version=2.1.0 +firebase-common-internal.version=2.1.0 +firebase-common.version=2.1.0 +firebase-config.version=2.1.0 +firebase-crashlytics.version=2.1.0 +firebase-database.version=2.1.0 +firebase-firestore.version=2.1.0 +firebase-functions.version=2.1.0 +firebase-installations.version=2.1.0 +firebase-messaging.version=2.1.0 +firebase-perf.version=2.1.0 +firebase-storage.version=2.1.0 From d8f82a570d79b3148d36d038a396dbc926c71d1e Mon Sep 17 00:00:00 2001 From: Andrew Reed Date: Mon, 2 Sep 2024 14:20:26 +0100 Subject: [PATCH 27/33] Updated readme --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 842a36cb7..2656b6ef0 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,17 @@ The following libraries are available for the various Firebase products. | Service or Product | Gradle Dependency | API Coverage | |---------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [Analytics](https://firebase.google.com/docs/analytics) | [`dev.gitlive:firebase-analytics:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-analytics/2.0.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) | -| [Authentication](https://firebase.google.com/docs/auth) | [`dev.gitlive:firebase-auth:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-auth/2.0.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) | -| [Realtime Database](https://firebase.google.com/docs/database) | [`dev.gitlive:firebase-database:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-database/2.0.0/pom) | [![70%](https://img.shields.io/badge/-70%25-orange?style=flat-square)](/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/database.kt) | -| [Cloud Firestore](https://firebase.google.com/docs/firestore) | [`dev.gitlive:firebase-firestore:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-firestore/2.0.0/pom) | [![60%](https://img.shields.io/badge/-60%25-orange?style=flat-square)](/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt) | -| [Cloud Functions](https://firebase.google.com/docs/functions) | [`dev.gitlive:firebase-functions:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-functions/2.0.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-functions/src/commonMain/kotlin/dev/gitlive/firebase/functions/functions.kt) | -| [Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) | [`dev.gitlive:firebase-messaging:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-messaging/2.0.0/pom) | [![1%](https://img.shields.io/badge/-10%25-orange?style=flat-square)](/firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt) | -| [Cloud Storage](https://firebase.google.com/docs/storage) | [`dev.gitlive:firebase-storage:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-storage/2.0.0/pom) | [![40%](https://img.shields.io/badge/-40%25-orange?style=flat-square)](/firebase-storage/src/commonMain/kotlin/dev/gitlive/firebase/storage/storage.kt) | -| [Installations](https://firebase.google.com/docs/projects/manage-installations) | [`dev.gitlive:firebase-installations:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-installations/2.0.0/pom) | [![90%](https://img.shields.io/badge/-90%25-green?style=flat-square)](/firebase-installations/src/commonMain/kotlin/dev/gitlive/firebase/installations/installations.kt) | -| [Remote Config](https://firebase.google.com/docs/remote-config) | [`dev.gitlive:firebase-config:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-config/2.0.0/pom) | [![20%](https://img.shields.io/badge/-20%25-orange?style=flat-square)](/firebase-config/src/commonMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfig.kt) | -| [Performance](https://firebase.google.com/docs/perf-mon) | [`dev.gitlive:firebase-perf:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-perf/2.0.0/pom) | [![1%](https://img.shields.io/badge/-10%25-orange?style=flat-square)](/firebase-perf/src/commonMain/kotlin/dev/gitlive/firebase/perf/performance.kt) | -| [Crashlytics](https://firebase.google.com/docs/crashlytics) | [`dev.gitlive:firebase-crashlytics:2.0.0`](https://search.maven.org/artifact/dev.gitlive/firebase-crashlytics/2.0.0/pom) | [![80%](https://img.shields.io/badge/-10%25-orange?style=flat-square)](/firebase-crashlytics/src/commonMain/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt) | +| [Analytics](https://firebase.google.com/docs/analytics) | [`dev.gitlive:firebase-analytics:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-analytics/2.1.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) | +| [Authentication](https://firebase.google.com/docs/auth) | [`dev.gitlive:firebase-auth:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-auth/2.1.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) | +| [Realtime Database](https://firebase.google.com/docs/database) | [`dev.gitlive:firebase-database:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-database/2.1.0/pom) | [![70%](https://img.shields.io/badge/-70%25-orange?style=flat-square)](/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/database.kt) | +| [Cloud Firestore](https://firebase.google.com/docs/firestore) | [`dev.gitlive:firebase-firestore:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-firestore/2.1.0/pom) | [![60%](https://img.shields.io/badge/-60%25-orange?style=flat-square)](/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt) | +| [Cloud Functions](https://firebase.google.com/docs/functions) | [`dev.gitlive:firebase-functions:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-functions/2.1.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-functions/src/commonMain/kotlin/dev/gitlive/firebase/functions/functions.kt) | +| [Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) | [`dev.gitlive:firebase-messaging:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-messaging/2.1.0/pom) | [![1%](https://img.shields.io/badge/-10%25-orange?style=flat-square)](/firebase-messaging/src/commonMain/kotlin/dev/gitlive/firebase/messaging/messaging.kt) | +| [Cloud Storage](https://firebase.google.com/docs/storage) | [`dev.gitlive:firebase-storage:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-storage/2.1.0/pom) | [![40%](https://img.shields.io/badge/-40%25-orange?style=flat-square)](/firebase-storage/src/commonMain/kotlin/dev/gitlive/firebase/storage/storage.kt) | +| [Installations](https://firebase.google.com/docs/projects/manage-installations) | [`dev.gitlive:firebase-installations:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-installations/2.1.0/pom) | [![90%](https://img.shields.io/badge/-90%25-green?style=flat-square)](/firebase-installations/src/commonMain/kotlin/dev/gitlive/firebase/installations/installations.kt) | +| [Remote Config](https://firebase.google.com/docs/remote-config) | [`dev.gitlive:firebase-config:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-config/2.1.0/pom) | [![20%](https://img.shields.io/badge/-20%25-orange?style=flat-square)](/firebase-config/src/commonMain/kotlin/dev/gitlive/firebase/remoteconfig/FirebaseRemoteConfig.kt) | +| [Performance](https://firebase.google.com/docs/perf-mon) | [`dev.gitlive:firebase-perf:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-perf/2.1.0/pom) | [![1%](https://img.shields.io/badge/-10%25-orange?style=flat-square)](/firebase-perf/src/commonMain/kotlin/dev/gitlive/firebase/perf/performance.kt) | +| [Crashlytics](https://firebase.google.com/docs/crashlytics) | [`dev.gitlive:firebase-crashlytics:2.1.0`](https://search.maven.org/artifact/dev.gitlive/firebase-crashlytics/2.1.0/pom) | [![80%](https://img.shields.io/badge/-10%25-orange?style=flat-square)](/firebase-crashlytics/src/commonMain/kotlin/dev/gitlive/firebase/crashlytics/crashlytics.kt) | Is the Firebase library or API you need missing? [Create an issue](https://github.com/GitLiveApp/firebase-kotlin-sdk/issues/new?labels=API+coverage&template=increase-api-coverage.md&title=Add+%5Bclass+name%5D.%5Bfunction+name%5D+to+%5Blibrary+name%5D+for+%5Bplatform+names%5D) to request additional API coverage or be awesome and [submit a PR](https://github.com/GitLiveApp/firebase-kotlin-sdk/fork) From c612f9c9e52874e5066d12925f22d41da7efccff Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 2 Sep 2024 17:37:10 +0200 Subject: [PATCH 28/33] Fixed some bugs and adding tests --- .../gitlive/firebase/internal/EncodersTest.kt | 41 + .../gitlive/firebase/internal/_encoders.kt | 2 +- .../api/android/firebase-firestore.api | 46 +- .../api/jvm/firebase-firestore.api | 46 +- .../dev/gitlive/firebase/firestore/Filter.kt | 4 +- .../gitlive/firebase/firestore/firestore.kt | 176 +-- .../firestore/DocumentReferenceTest.kt | 397 +++++++ .../firebase/firestore/FirestoreSourceTest.kt | 2 +- .../gitlive/firebase/firestore/QueryTest.kt | 657 +++++++++++ .../firebase/firestore/WriteBatchTest.kt | 220 ++++ .../gitlive/firebase/firestore/firestore.kt | 1014 +---------------- 11 files changed, 1492 insertions(+), 1113 deletions(-) create mode 100644 firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt create mode 100644 firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt create mode 100644 firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt diff --git a/firebase-common-internal/src/commonTest/kotlin/dev/gitlive/firebase/internal/EncodersTest.kt b/firebase-common-internal/src/commonTest/kotlin/dev/gitlive/firebase/internal/EncodersTest.kt index 145d57b74..2017f8dc6 100644 --- a/firebase-common-internal/src/commonTest/kotlin/dev/gitlive/firebase/internal/EncodersTest.kt +++ b/firebase-common-internal/src/commonTest/kotlin/dev/gitlive/firebase/internal/EncodersTest.kt @@ -262,6 +262,47 @@ class EncodersTest { assertEquals(nestedClass, decoded) } + @Test + fun encodeDecodeNestedClassWithEmptyCollections() { + val module = SerializersModule { + polymorphic(AbstractClass::class, AbstractClass.serializer()) { + subclass(ImplementedClass::class, ImplementedClass.serializer()) + } + } + + val testData = TestData(mapOf(), mapOf(), true, null, ValueClass(42)) + val sealedClass: SealedClass = SealedClass.Test("value") + val abstractClass: AbstractClass = ImplementedClass("value", true) + val nestedClass = NestedClass(testData, sealedClass, abstractClass, listOf(), listOf(), listOf(), mapOf(), mapOf(), mapOf()) + val encoded = encode(NestedClass.serializer(), nestedClass) { + encodeDefaults = true + serializersModule = module + } + + val testDataEncoded = nativeMapOf("map" to nativeMapOf(), "otherMap" to nativeMapOf(), "bool" to true, "nullableBool" to null, "valueClass" to 42) + val sealedEncoded = nativeMapOf("type" to "test", "value" to "value") + val abstractEncoded = nativeMapOf("type" to "implemented", "abstractValue" to "value", "otherValue" to true) + nativeAssertEquals( + nativeMapOf( + "testData" to testDataEncoded, + "sealed" to sealedEncoded, + "abstract" to abstractEncoded, + "testDataList" to nativeListOf(), + "sealedList" to nativeListOf(), + "abstractList" to nativeListOf(), + "testDataMap" to nativeMapOf(), + "sealedMap" to nativeMapOf(), + "abstractMap" to nativeMapOf(), + ), + encoded, + ) + + val decoded = decode(NestedClass.serializer(), encoded) { + serializersModule = module + } + assertEquals(nestedClass, decoded) + } + @Test fun reencodeTransformationList() { val reencoded = reencodeTransformation>(nativeListOf("One", "Two", "Three")) { diff --git a/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt b/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt index 7121128d0..091d9c2da 100644 --- a/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt +++ b/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt @@ -28,7 +28,7 @@ internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescr else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") } -private fun FirebaseEncoderImpl.encodeAsList(descriptor: SerialDescriptor): FirebaseCompositeEncoder = Array(descriptor.elementsCount) { null } +private fun FirebaseEncoderImpl.encodeAsList(descriptor: SerialDescriptor): FirebaseCompositeEncoder = Array(descriptor.elementsCount - 1) { null } .also { value = it } .let { FirebaseCompositeEncoder(settings) { _, index, value -> it[index] = value } } private fun FirebaseEncoderImpl.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = json() diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index d02f12da2..9cf847e6b 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -68,15 +68,15 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/DocumentReference;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public fun toString ()Ljava/lang/String; + public final fun update (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateEncoded (Ldev/gitlive/firebase/internal/EncodedObject;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateWithBuilder (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFieldPaths (Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields (Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields ([Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -442,12 +442,12 @@ public class dev/gitlive/firebase/firestore/Query { public static final field Companion Ldev/gitlive/firebase/firestore/Query$Companion; public final fun endAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun endAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endBefore$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun get (Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun get$default (Ldev/gitlive/firebase/firestore/Query;Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getSnapshots ()Lkotlinx/coroutines/flow/Flow; @@ -460,12 +460,12 @@ public class dev/gitlive/firebase/firestore/Query { public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/Query;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public final fun startAfter (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun startAfter (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAfter$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun where (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; } @@ -581,16 +581,16 @@ public final class dev/gitlive/firebase/firestore/Transaction { public fun toString ()Ljava/lang/String; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -719,15 +719,15 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun set$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;[Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun setEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;Ldev/gitlive/firebase/firestore/internal/SetOptions;)Ldev/gitlive/firebase/firestore/WriteBatch; public fun toString ()Ljava/lang/String; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index fee19cb9b..6b5abda69 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -68,15 +68,15 @@ public final class dev/gitlive/firebase/firestore/DocumentReference { public final fun snapshots (Z)Lkotlinx/coroutines/flow/Flow; public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/DocumentReference;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public fun toString ()Ljava/lang/String; + public final fun update (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun update (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun updateEncoded (Ldev/gitlive/firebase/internal/EncodedObject;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; - public final fun updateWithBuilder (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFieldPaths (Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFieldPaths ([Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields (Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields ([Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -442,12 +442,12 @@ public class dev/gitlive/firebase/firestore/Query { public static final field Companion Ldev/gitlive/firebase/firestore/Query$Companion; public final fun endAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun endAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun endBefore (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun endBefore$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBefore ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun get (Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static synthetic fun get$default (Ldev/gitlive/firebase/firestore/Query;Ldev/gitlive/firebase/firestore/Source;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun getSnapshots ()Lkotlinx/coroutines/flow/Flow; @@ -460,12 +460,12 @@ public class dev/gitlive/firebase/firestore/Query { public static synthetic fun snapshots$default (Ldev/gitlive/firebase/firestore/Query;ZILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow; public final fun startAfter (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun startAfter (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAfter$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfter ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Ldev/gitlive/firebase/firestore/DocumentSnapshot;)Ldev/gitlive/firebase/firestore/Query; public final fun startAt (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public final fun startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; - public static synthetic fun startAt$default (Ldev/gitlive/firebase/firestore/Query;[Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt (Lkotlin/jvm/functions/Function1;[Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAt ([Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/Query; public final fun where (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; } @@ -581,16 +581,16 @@ public final class dev/gitlive/firebase/firestore/Transaction { public fun toString ()Ljava/lang/String; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFieldPaths$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; - public static synthetic fun updateFields$default (Ldev/gitlive/firebase/firestore/Transaction;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/Transaction; - public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/Transaction; } public final class dev/gitlive/firebase/firestore/Transaction$Companion { @@ -719,15 +719,15 @@ public final class dev/gitlive/firebase/firestore/WriteBatch { public static synthetic fun set$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;[Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun setEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;Ldev/gitlive/firebase/firestore/internal/SetOptions;)Ldev/gitlive/firebase/firestore/WriteBatch; public fun toString ()Ljava/lang/String; + public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun update (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ldev/gitlive/firebase/firestore/WriteBatch; public static synthetic fun update$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateEncoded (Ldev/gitlive/firebase/firestore/DocumentReference;Ldev/gitlive/firebase/internal/EncodedObject;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateField$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; - public static synthetic fun updateFieldPath$default (Ldev/gitlive/firebase/firestore/WriteBatch;Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/firestore/WriteBatch; - public final fun updateWithBuilder (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; + public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)Ldev/gitlive/firebase/firestore/WriteBatch; } public final class dev/gitlive/firebase/firestore/WriteBatch$Companion { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt index 3b3f33a55..3f5785c9f 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/Filter.kt @@ -136,7 +136,7 @@ public class FilterBuilder internal constructor() { ) public fun FieldPath.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( @@ -154,7 +154,7 @@ public class FilterBuilder internal constructor() { ) public fun FieldPath.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!), ) public inline infix fun String.contains(value: T): Filter.WithConstraint = Filter.Field( diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 7c149daac..c87f4194c 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -178,38 +178,50 @@ public data class Transaction internal constructor(internal val nativeWrapper: N internal fun setEncoded(documentRef: DocumentReference, encodedData: EncodedObject, setOptions: SetOptions): Transaction = Transaction(nativeWrapper.setEncoded(documentRef, encodedData, setOptions)) @Deprecated("Deprecated. Use builder instead", replaceWith = ReplaceWith("update(documentRef, data) { this.encodeDefaults = encodeDefaults }")) - public fun update(documentRef: DocumentReference, data: Any, encodeDefaults: Boolean): Transaction = update(documentRef, data) { - this.encodeDefaults = encodeDefaults - } + public fun update(documentRef: DocumentReference, data: Any, encodeDefaults: Boolean): Transaction = + update(documentRef, data) { + this.encodeDefaults = encodeDefaults + } public inline fun update(documentRef: DocumentReference, data: Any, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncoded(documentRef, encodeAsObject(data, buildSettings)) @Deprecated("Deprecated. Use builder instead", replaceWith = ReplaceWith("update(documentRef, strategy, data) { this.encodeDefaults = encodeDefaults }")) - public fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, encodeDefaults: Boolean): Transaction = update(documentRef, strategy, data) { - this.encodeDefaults = encodeDefaults - } + public fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, encodeDefaults: Boolean): Transaction = + update(documentRef, strategy, data) { + this.encodeDefaults = encodeDefaults + } public inline fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateEncoded(documentRef, encodeAsObject(strategy, data, buildSettings)) @JvmName("updateFields") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateWithBuilder( - documentRef, - ) { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): Transaction = + update(documentRef, {}, *fieldsAndValues) + + @JvmName("updateFields") + public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Transaction = + update( + documentRef, + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } } - } @JvmName("updateFieldPaths") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Transaction = updateWithBuilder( - documentRef, - ) { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): Transaction = + update(documentRef, {}, *fieldsAndValues) + + @JvmName("updateFieldPaths") + public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Transaction = + update( + documentRef, + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } } - } - public fun updateWithBuilder( + public fun update( documentRef: DocumentReference, fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) @@ -242,47 +254,51 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun orderBy(field: FieldPath, direction: Direction = Direction.ASCENDING): Query = Query(nativeQuery.orderBy(field.encoded, direction)) public fun startAfter(document: DocumentSnapshot): Query = Query(nativeQuery.startAfter(document.native)) - public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAfter( - builder = { + public fun startAfter(vararg fieldValues: Any?): Query = startAfter({}, *fieldValues) + public fun startAfter(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = + startAfter { this.buildSettings = buildSettings fieldValues.forEach { add(it) } - }, - ) + } + public fun startAfter(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAfter(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun startAt(document: DocumentSnapshot): Query = Query(nativeQuery.startAt(document.native)) - public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = startAt( - builder = { + public fun startAt(vararg fieldValues: Any?): Query = startAt({}, *fieldValues) + public fun startAt(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = + startAt { this.buildSettings = buildSettings fieldValues.forEach { add(it) } - }, - ) + } + public fun startAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun endBefore(document: DocumentSnapshot): Query = Query(nativeQuery.endBefore(document.native)) - public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endBefore( - builder = { + public fun endBefore(vararg fieldValues: Any?): Query = endBefore({}, *fieldValues) + public fun endBefore(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = + endBefore { this.buildSettings = buildSettings fieldValues.forEach { add(it) } - }, - ) + } + public fun endBefore(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endBefore(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun endAt(document: DocumentSnapshot): Query = Query(nativeQuery.endAt(document.native)) - public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Query = endAt( - builder = { + public fun endAt(vararg fieldValues: Any?): Query = endAt({}, *fieldValues) + public fun endAt(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = + endAt { this.buildSettings = buildSettings fieldValues.forEach { add(it) } - }, - ) + } + public fun endAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) } @@ -394,40 +410,52 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na internal fun setEncoded(documentRef: DocumentReference, encodedData: EncodedObject, setOptions: SetOptions): WriteBatch = WriteBatch(nativeWrapper.setEncoded(documentRef, encodedData, setOptions)) @Deprecated("Deprecated. Use builder instead", replaceWith = ReplaceWith("update(documentRef, data) { this.encodeDefaults = encodeDefaults }")) - public inline fun update(documentRef: DocumentReference, data: T, encodeDefaults: Boolean): WriteBatch = update(documentRef, data) { - this.encodeDefaults = encodeDefaults - } + public inline fun update(documentRef: DocumentReference, data: T, encodeDefaults: Boolean): WriteBatch = + update(documentRef, data) { + this.encodeDefaults = encodeDefaults + } public inline fun update(documentRef: DocumentReference, data: T, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncoded(documentRef, encodeAsObject(data, buildSettings)) @Deprecated("Deprecated. Use builder instead", replaceWith = ReplaceWith("update(documentRef, strategy, data) { this.encodeDefaults = encodeDefaults }")) - public fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, encodeDefaults: Boolean): WriteBatch = update(documentRef, strategy, data) { - this.encodeDefaults = encodeDefaults - } + public fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, encodeDefaults: Boolean): WriteBatch = + update(documentRef, strategy, data) { + this.encodeDefaults = encodeDefaults + } public inline fun update(documentRef: DocumentReference, strategy: SerializationStrategy, data: T, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateEncoded(documentRef, encodeAsObject(strategy, data, buildSettings)) @JvmName("updateField") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateWithBuilder( - documentRef, - ) { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): WriteBatch = + update(documentRef, {}, *fieldsAndValues) + + @JvmName("updateField") + public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): WriteBatch = + update( + documentRef, + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } } - } @JvmName("updateFieldPath") - public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): WriteBatch = updateWithBuilder( - documentRef, - ) { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (path, value) -> - path to value + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): WriteBatch = + update(documentRef, {}, *fieldsAndValues) + + @JvmName("updateFieldPath") + public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): WriteBatch = + update( + documentRef, + ) { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (path, value) -> + path to value + } } - } - public fun updateWithBuilder( + public fun update( documentRef: DocumentReference, fieldAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ): WriteBatch = WriteBatch( @@ -577,22 +605,32 @@ public data class DocumentReference internal constructor(internal val native: Na } @JvmName("updateFields") - public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = updateWithBuilder { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (field, value) -> - field to value + public suspend fun update(vararg fieldsAndValues: Pair): Unit = + update({}, *fieldsAndValues) + + @JvmName("updateFields") + public suspend fun update(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Unit = + update { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (field, value) -> + field to value + } } - } @JvmName("updateFieldPaths") - public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit = {}): Unit = updateWithBuilder { - this.buildSettings = buildSettings - fieldsAndValues.forEach { (fieldPath, value) -> - fieldPath to value + public suspend fun update(vararg fieldsAndValues: Pair): Unit = + update({}, *fieldsAndValues) + + @JvmName("updateFieldPaths") + public suspend fun update(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Unit = + update { + this.buildSettings = buildSettings + fieldsAndValues.forEach { (fieldPath, value) -> + fieldPath to value + } } - } - public suspend fun updateWithBuilder( + public suspend fun update( fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ) { native.updateEncoded(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt new file mode 100644 index 000000000..446dbb4ab --- /dev/null +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt @@ -0,0 +1,397 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.internal.decode +import dev.gitlive.firebase.runTest +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.withContext +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.nullable +import kotlinx.serialization.builtins.serializer +import kotlin.random.Random +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds + +@IgnoreForAndroidUnitTest +class DocumentReferenceTest : BaseFirebaseFirestoreTest() { + + @Serializable + data class FirestoreTimeTest( + val prop1: String, + val time: BaseTimestamp?, + ) + + @Serializable + data class TestDataWithDocumentReference( + val uid: String, + val reference: DocumentReference, + val optionalReference: DocumentReference?, + ) + + @Serializable + data class TestDataWithOptionalDocumentReference( + val optionalReference: DocumentReference?, + ) + + @Test + fun encodeDocumentReference() = runTest { + val doc = firestore.document("a/b") + val item = TestDataWithDocumentReference("123", doc, doc) + val encoded = encodedAsMap( + encode(item) { + encodeDefaults = false + }, + ) + assertEquals("123", encoded["uid"]) + assertEquals(doc.nativeValue, encoded["reference"]) + assertEquals(doc.nativeValue, encoded["optionalReference"]) + } + + @Test + fun encodeNullDocumentReference() = runTest { + val item = TestDataWithOptionalDocumentReference(null) + val encoded = encodedAsMap( + encode(item) { + encodeDefaults = false + }, + ) + assertNull(encoded["optionalReference"]) + } + + @Test + fun decodeDocumentReference() = runTest { + val doc = firestore.document("a/b") + val obj = mapOf( + "uid" to "123", + "reference" to doc.nativeValue, + "optionalReference" to doc.nativeValue, + ).asEncoded() + val decoded: TestDataWithDocumentReference = decode(obj) + assertEquals("123", decoded.uid) + assertEquals(doc.path, decoded.reference.path) + assertEquals(doc.path, decoded.optionalReference?.path) + } + + @Test + fun decodeNullDocumentReference() = runTest { + val obj = mapOf("optionalReference" to null).asEncoded() + val decoded: TestDataWithOptionalDocumentReference = decode(obj) + assertNull(decoded.optionalReference?.path) + } + + @Test + fun testServerTimestampFieldValue() = runTest { + val doc = firestore + .collection("testServerTimestampFieldValue") + .document("test") + doc.set( + FirestoreTimeTest.serializer(), + FirestoreTimeTest("ServerTimestamp", Timestamp(123, 0)), + ) + assertEquals(Timestamp(123, 0), doc.get().get("time", TimestampSerializer)) + + doc.set(FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestamp", Timestamp.ServerTimestamp)) + + assertNotEquals(Timestamp.ServerTimestamp, doc.get().get("time", BaseTimestamp.serializer())) + assertNotEquals(Timestamp.ServerTimestamp, doc.get().data(FirestoreTimeTest.serializer()).time) + } + + @Test + fun testServerTimestampBehaviorNone() = runTest { + val doc = firestore + .collection("testServerTimestampBehaviorNone") + .document("test${Random.nextInt()}") + + val deferredPendingWritesSnapshot = async { + doc.snapshots.filter { it.exists }.first() + } + nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot + + doc.set( + FirestoreTimeTest.serializer(), + FirestoreTimeTest("ServerTimestampBehavior", Timestamp.ServerTimestamp), + ) + + val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() + assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) + assertNull(pendingWritesSnapshot.get("time", BaseTimestamp.serializer().nullable, serverTimestampBehavior = ServerTimestampBehavior.NONE)) + } + + @Test + fun testServerTimestampBehaviorEstimate() = runTest { + val doc = firestore + .collection("testServerTimestampBehaviorEstimate") + .document("test${Random.nextInt()}") + + val deferredPendingWritesSnapshot = async { + doc.snapshots.filter { it.exists }.first() + } + nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot + + doc.set(FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestampBehavior", Timestamp.ServerTimestamp)) + + val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() + assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) + assertNotNull(pendingWritesSnapshot.get("time", ServerTimestampBehavior.ESTIMATE)) + assertNotEquals(Timestamp.ServerTimestamp, pendingWritesSnapshot.data(FirestoreTimeTest.serializer(), serverTimestampBehavior = ServerTimestampBehavior.ESTIMATE).time) + } + + @Test + fun testServerTimestampBehaviorPrevious() = runTest { + val doc = firestore + .collection("testServerTimestampBehaviorPrevious") + .document("test${Random.nextInt()}") + + val deferredPendingWritesSnapshot = async { + doc.snapshots.filter { it.exists }.first() + } + nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot + + doc.set(FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestampBehavior", Timestamp.ServerTimestamp)) + + val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() + assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) + assertNull(pendingWritesSnapshot.get("time", BaseTimestamp.serializer().nullable, serverTimestampBehavior = ServerTimestampBehavior.PREVIOUS)) + } + + @Test + fun testDocumentAutoId() = runTest { + val doc = firestore + .collection("testDocumentAutoId") + .document + + doc.set(FirestoreTest.serializer(), FirestoreTest("AutoId")) + + val resultDoc = firestore + .collection("testDocumentAutoId") + .document(doc.id) + .get() + + assertEquals(true, resultDoc.exists) + assertEquals("AutoId", resultDoc.get("prop1")) + } + + @Test + fun testUpdateValues() = runTest { + val doc = firestore + .collection("testFirestoreUpdateMultipleValues") + .document("test1") + + doc.set(FirestoreTest.serializer(), FirestoreTest("property", count = 0, nested = NestedObject("nested"), duration = 600.milliseconds)) + val dataBefore = doc.get().data(FirestoreTest.serializer()) + assertEquals(0, dataBefore.count) + assertNull(dataBefore.optional) + assertEquals(NestedObject("nested"), dataBefore.nested) + assertEquals(600.milliseconds, dataBefore.duration) + + doc.update { + FirestoreTest::count.name to 5 + FieldPath(FirestoreTest::optional.name) to "notNull" + FirestoreTest::nested.name.to(NestedObject.serializer(), NestedObject("newProperty")) + FieldPath(FirestoreTest::duration.name).to(DurationAsLongSerializer(), 700.milliseconds) + } + val dataAfter = doc.get().data(FirestoreTest.serializer()) + assertEquals(5, dataAfter.count) + assertEquals("notNull", dataAfter.optional) + assertEquals(NestedObject("newProperty"), dataAfter.nested) + assertEquals(700.milliseconds, dataAfter.duration) + } + + @Test + fun testIncrementFieldValue() = runTest { + val doc = firestore + .collection("testFirestoreIncrementFieldValue") + .document("test1") + + doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", count = 0)) + val dataBefore = doc.get().data(FirestoreTest.serializer()) + assertEquals(0, dataBefore.count) + + doc.update("count" to FieldValue.increment(5)) + val dataAfter = doc.get().data(FirestoreTest.serializer()) + assertEquals(5, dataAfter.count) + } + + @Test + fun testArrayUnion() = runTest { + val doc = firestore + .collection("testFirestoreArrayUnion") + .document("test1") + + doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", list = listOf("first"))) + val dataBefore = doc.get().data(FirestoreTest.serializer()) + assertEquals(listOf("first"), dataBefore.list) + + doc.update("list" to FieldValue.arrayUnion("second")) + val dataAfter = doc.get().data(FirestoreTest.serializer()) + assertEquals(listOf("first", "second"), dataAfter.list) + } + + @Test + fun testArrayRemove() = runTest { + val doc = firestore + .collection("testFirestoreArrayRemove") + .document("test1") + + doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", list = listOf("first", "second"))) + val dataBefore = doc.get().data(FirestoreTest.serializer()) + assertEquals(listOf("first", "second"), dataBefore.list) + + doc.update("list" to FieldValue.arrayRemove("second")) + val dataAfter = doc.get().data(FirestoreTest.serializer()) + assertEquals(listOf("first"), dataAfter.list) + } + + @Test + fun testLegacyDoubleTimestamp() = runTest { + @Serializable + data class DoubleTimestamp( + @Serializable(with = DoubleAsTimestampSerializer::class) + val time: Double?, + ) + + val doc = firestore + .collection("testLegacyDoubleTimestamp") + .document("test${Random.nextInt()}") + + val deferredPendingWritesSnapshot = async { + doc.snapshots.filter { it.exists }.first() + } + nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot + + doc.set(DoubleTimestamp.serializer(), DoubleTimestamp(DoubleAsTimestampSerializer.SERVER_TIMESTAMP)) + + val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() + assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) + assertNotNull(pendingWritesSnapshot.get("time", DoubleAsTimestampSerializer, serverTimestampBehavior = ServerTimestampBehavior.ESTIMATE)) + assertNotEquals(DoubleAsTimestampSerializer.SERVER_TIMESTAMP, pendingWritesSnapshot.data(DoubleTimestamp.serializer(), serverTimestampBehavior = ServerTimestampBehavior.ESTIMATE).time) + } + + @Test + fun testLegacyDoubleTimestampWriteNewFormatRead() = runTest { + @Serializable + data class LegacyDocument( + @Serializable(with = DoubleAsTimestampSerializer::class) + val time: Double, + ) + + @Serializable + data class NewDocument( + val time: Timestamp, + ) + + val doc = firestore + .collection("testLegacyDoubleTimestampEncodeDecode") + .document("testLegacy") + + val ms = 12345678.0 + + doc.set(LegacyDocument.serializer(), LegacyDocument(time = ms)) + + val fetched: NewDocument = doc.get().data(NewDocument.serializer()) + assertEquals(ms, fetched.time.toMilliseconds()) + } + + @Test + fun testGeoPointSerialization() = runTest { + @Serializable + data class DataWithGeoPoint(val geoPoint: GeoPoint) + + fun getDocument() = firestore.collection("geoPointSerialization") + .document("geoPointSerialization") + + val data = DataWithGeoPoint(GeoPoint(12.34, 56.78)) + // store geo point + getDocument().set(DataWithGeoPoint.serializer(), data) + // restore data + val savedData = getDocument().get().data(DataWithGeoPoint.serializer()) + assertEquals(data.geoPoint, savedData.geoPoint) + + // update data + val updatedData = DataWithGeoPoint(GeoPoint(87.65, 43.21)) + getDocument().update(FieldPath(DataWithGeoPoint::geoPoint.name) to updatedData.geoPoint) + // verify update + val updatedSavedData = getDocument().get().data(DataWithGeoPoint.serializer()) + assertEquals(updatedData.geoPoint, updatedSavedData.geoPoint) + } + + @Test + fun testDocumentReferenceSerialization() = runTest { + @Serializable + data class DataWithDocumentReference( + val documentReference: DocumentReference, + ) + + fun getCollection() = firestore.collection("documentReferenceSerialization") + fun getDocument() = getCollection() + .document("documentReferenceSerialization") + val documentRef1 = getCollection().document("refDoc1").apply { + set(mapOf("value" to 1)) + } + val documentRef2 = getCollection().document("refDoc2").apply { + set(mapOf("value" to 2)) + } + + val data = DataWithDocumentReference(documentRef1) + // store reference + getDocument().set(DataWithDocumentReference.serializer(), data) + // restore data + val savedData = getDocument().get().data(DataWithDocumentReference.serializer()) + assertEquals(data.documentReference.path, savedData.documentReference.path) + + // update data + val updatedData = DataWithDocumentReference(documentRef2) + getDocument().update { + FieldPath(DataWithDocumentReference::documentReference.name).to( + DocumentReferenceSerializer, + updatedData.documentReference, + ) + } + // verify update + val updatedSavedData = getDocument().get().data(DataWithDocumentReference.serializer()) + assertEquals(updatedData.documentReference.path, updatedSavedData.documentReference.path) + } + + @Test + fun testFieldValuesOps() = runTest { + @Serializable + data class TestData(val values: List) + fun getDocument() = firestore.collection("fieldValuesOps") + .document("fieldValuesOps") + + val data = TestData(listOf(1)) + // store + getDocument().set(TestData.serializer(), data) + // append & verify + getDocument().update(FieldPath(TestData::values.name) to FieldValue.arrayUnion(2)) + + var savedData = getDocument().get().data(TestData.serializer()) + assertEquals(listOf(1, 2), savedData.values) + + // remove & verify + getDocument().update(FieldPath(TestData::values.name) to FieldValue.arrayRemove(1)) + savedData = getDocument().get().data(TestData.serializer()) + assertEquals(listOf(2), savedData.values) + + val list = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) + assertEquals(listOf(2), list) + // delete & verify + getDocument().update(FieldPath(TestData::values.name) to FieldValue.delete) + val deletedList = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) + assertNull(deletedList) + } + + private suspend fun nonSkippedDelay(timeout: Duration) = withContext(Dispatchers.Default) { + delay(timeout) + } +} diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt index 2a5d74d90..ecc5b386b 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt @@ -12,7 +12,7 @@ class FirestoreSourceTest { lateinit var firestore: FirebaseFirestore companion object { - val testDoc = FirebaseFirestoreTest.FirestoreTest( + val testDoc = BaseFirebaseFirestoreTest.FirestoreTest( "aaa", 0.0, 1, diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt new file mode 100644 index 000000000..9d25c5102 --- /dev/null +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt @@ -0,0 +1,657 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.runTest +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.time.Duration.Companion.milliseconds + +open class QueryTest : BaseFirebaseFirestoreTest() { + + companion object { + const val COLLECTION = "testFirestoreQuerying" + val testOne = FirestoreTest( + "aaa", + 0.0, + 1, + listOf("a", "aa", "aaa"), + "notNull", + NestedObject("ddd"), + listOf(NestedObject("l1"), NestedObject("l2"), NestedObject("l3")), + 100.milliseconds, + ) + val testTwo = FirestoreTest( + "bbb", + 0.0, + 2, + listOf("b", "bb", "ccc"), + null, + NestedObject("eee"), + listOf(NestedObject("l2"), NestedObject("l4"), NestedObject("l5")), + 200.milliseconds, + ) + val testThree = FirestoreTest( + "ccc", + 1.0, + 3, + listOf("c", "cc", "ccc"), + "notNull", + NestedObject("fff"), + listOf(NestedObject("l3"), NestedObject("l6"), NestedObject("l7")), + 300.milliseconds, + ) + } + + private val collection get() = firestore.collection(COLLECTION) + + @Test + fun testStringOrderBy() = runTestWithFirestoreData { + val resultDocs = collection + .orderBy(FirestoreTest::prop1.name) + .get() + .documents + assertEquals(3, resultDocs.size) + assertEquals("aaa", resultDocs[0].get(FirestoreTest::prop1.name)) + assertEquals("bbb", resultDocs[1].get(FirestoreTest::prop1.name)) + assertEquals("ccc", resultDocs[2].get(FirestoreTest::prop1.name)) + } + + @Test + fun testFieldOrderBy() = runTestWithFirestoreData { + val resultDocs = firestore.collection(COLLECTION) + .orderBy(FieldPath(FirestoreTest::prop1.name)).get().documents + assertEquals(3, resultDocs.size) + assertEquals("aaa", resultDocs[0].get(FirestoreTest::prop1.name)) + assertEquals("bbb", resultDocs[1].get(FirestoreTest::prop1.name)) + assertEquals("ccc", resultDocs[2].get(FirestoreTest::prop1.name)) + } + + @Test + fun testStringOrderByAscending() = runTestWithFirestoreData { + val resultDocs = firestore.collection(COLLECTION) + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING).get().documents + assertEquals(3, resultDocs.size) + assertEquals("aaa", resultDocs[0].get(FirestoreTest::prop1.name)) + assertEquals("bbb", resultDocs[1].get(FirestoreTest::prop1.name)) + assertEquals("ccc", resultDocs[2].get(FirestoreTest::prop1.name)) + } + + @Test + fun testFieldOrderByAscending() = runTestWithFirestoreData { + val resultDocs = firestore.collection(COLLECTION) + .orderBy(FieldPath(FirestoreTest::prop1.name), Direction.ASCENDING).get().documents + assertEquals(3, resultDocs.size) + assertEquals("aaa", resultDocs[0].get(FirestoreTest::prop1.name)) + assertEquals("bbb", resultDocs[1].get(FirestoreTest::prop1.name)) + assertEquals("ccc", resultDocs[2].get(FirestoreTest::prop1.name)) + } + + @Test + fun testStringOrderByDescending() = runTestWithFirestoreData { + val resultDocs = firestore.collection(COLLECTION) + .orderBy(FirestoreTest::prop1.name, Direction.DESCENDING).get().documents + assertEquals(3, resultDocs.size) + assertEquals("ccc", resultDocs[0].get(FirestoreTest::prop1.name)) + assertEquals("bbb", resultDocs[1].get(FirestoreTest::prop1.name)) + assertEquals("aaa", resultDocs[2].get(FirestoreTest::prop1.name)) + } + + @Test + fun testFieldOrderByDescending() = runTestWithFirestoreData { + val resultDocs = firestore.collection(COLLECTION) + .orderBy(FieldPath(FirestoreTest::prop1.name), Direction.DESCENDING).get().documents + assertEquals(3, resultDocs.size) + assertEquals("ccc", resultDocs[0].get(FirestoreTest::prop1.name)) + assertEquals("bbb", resultDocs[1].get(FirestoreTest::prop1.name)) + assertEquals("aaa", resultDocs[2].get(FirestoreTest::prop1.name)) + } + + @Test + fun testQueryEqualTo() = runTestWithFirestoreData { + val fieldQuery = collection + .where { FirestoreTest::prop1.name equalTo testOne.prop1 } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::prop1.name) equalTo testTwo.prop1 } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testTwo) + + val nullableQuery = collection + .where { FieldPath(FirestoreTest::optional.name).isNull } + + nullableQuery.assertDocuments(FirestoreTest.serializer(), testTwo) + + val serializeFieldQuery = collection.where { + FirestoreTest::nested.name.equalTo(NestedObject.serializer(), testOne.nested!!) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::nested.name).equalTo(NestedObject.serializer(), testTwo.nested!!) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testTwo) + } + + @Test + fun testQueryNotEqualTo() = runTestWithFirestoreData { + val fieldQuery = collection + .where { FirestoreTest::prop1.name notEqualTo testOne.prop1 } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::prop1.name) notEqualTo testTwo.prop1 } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) + + val nullableQuery = collection + .where { FieldPath(FirestoreTest::optional.name).isNotNull } + + nullableQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) + + val serializeFieldQuery = collection.where { + FirestoreTest::nested.name.notEqualTo(NestedObject.serializer(), testOne.nested!!) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::nested.name).notEqualTo(NestedObject.serializer(), testTwo.nested!!) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) + } + + @Test + fun testQueryLessThan() = runTestWithFirestoreData { + val fieldQuery = collection + .where { "count" lessThan testThree.count } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::count.name) lessThan testTwo.count } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val serializeFieldQuery = collection.where { + "duration".lessThan(DurationAsLongSerializer(), testThree.duration) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::duration.name).lessThan(DurationAsLongSerializer(), testTwo.duration) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne) + } + + @Test + fun testQueryGreaterThan() = runTestWithFirestoreData { + val fieldQuery = collection + .where { "count" greaterThan testOne.count } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::count.name) greaterThan testTwo.count } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) + + val serializeFieldQuery = collection.where { + "duration".greaterThan(DurationAsLongSerializer(), testOne.duration) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::duration.name).greaterThan(DurationAsLongSerializer(), testTwo.duration) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testThree) + } + + @Test + fun testQueryLessThanOrEqualTo() = runTestWithFirestoreData { + val fieldQuery = collection + .where { "count" lessThanOrEqualTo testOne.count } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::count.name) lessThanOrEqualTo testTwo.count } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val serializeFieldQuery = collection.where { + "duration".lessThanOrEqualTo(DurationAsLongSerializer(), testOne.duration) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::duration.name).lessThanOrEqualTo(DurationAsLongSerializer(), testTwo.duration) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + } + + @Test + fun testQueryGreaterThanOrEqualTo() = runTestWithFirestoreData { + val fieldQuery = collection + .where { "count" greaterThanOrEqualTo testThree.count } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testThree) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::count.name) greaterThanOrEqualTo testTwo.count } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val serializeFieldQuery = collection.where { + "duration".greaterThanOrEqualTo(DurationAsLongSerializer(), testTwo.duration) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::duration.name).greaterThanOrEqualTo(DurationAsLongSerializer(), testThree.duration) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testThree) + } + + @Test + fun testQueryArrayContains() = runTestWithFirestoreData { + val fieldQuery = collection + .where { "list" contains "a" } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::list.name) contains "ccc" } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testThree, testTwo) + + val serializeFieldQuery = collection.where { + "nestedList".contains(NestedObject.serializer(), NestedObject("l2")) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::nestedList.name).contains(NestedObject.serializer(), NestedObject("l3")) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) + } + + @Test + fun testQueryArrayContainsAny() = runTestWithFirestoreData { + val fieldQuery = collection + .where { "list" containsAny listOf("a", "b") } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::list.name) containsAny listOf("c", "d") } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) + + val serializeFieldQuery = collection.where { + "nestedList".containsAny(NestedObject.serializer(), listOf(NestedObject("l1"), NestedObject("l4"))) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::nestedList.name).containsAny(NestedObject.serializer(), listOf(NestedObject("l5"), NestedObject("l7"))) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testThree, testTwo) + } + + @Test + fun testQueryInArray() = runTestWithFirestoreData { + val fieldQuery = collection + .where { FirestoreTest::prop1.name inArray listOf("aaa", "bbb") } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::prop1.name) inArray listOf("ccc", "ddd") } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) + + val serializeFieldQuery = collection.where { + FirestoreTest::nested.name.inArray(NestedObject.serializer(), listOf(NestedObject("ddd"), NestedObject("eee"))) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::nested.name).inArray(NestedObject.serializer(), listOf(NestedObject("eee"), NestedObject("fff"))) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testThree, testTwo) + } + + @Test + fun testQueryNotInArray() = runTestWithFirestoreData { + val fieldQuery = collection + .where { FirestoreTest::prop1.name notInArray listOf("aaa", "bbb") } + + fieldQuery.assertDocuments(FirestoreTest.serializer(), testThree) + + val pathQuery = collection + .where { FieldPath(FirestoreTest::prop1.name) notInArray listOf("ccc", "ddd") } + + pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val serializeFieldQuery = collection.where { + FirestoreTest::nested.name.notInArray(NestedObject.serializer(), listOf(NestedObject("ddd"), NestedObject("eee"))) + } + serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testThree) + + val serializePathQuery = collection.where { + FieldPath(FirestoreTest::nested.name).notInArray(NestedObject.serializer(), listOf(NestedObject("eee"), NestedObject("fff"))) + } + serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne) + } + + @Test + fun testCompoundQuery() = runTestWithFirestoreData { + val andQuery = collection + .where { + FieldPath(FirestoreTest::prop1.name) inArray listOf("aaa", "bbb") and (FieldPath(FirestoreTest::count.name) equalTo 1) + } + andQuery.assertDocuments(FirestoreTest.serializer(), testOne) + + val orQuery = collection + .where { + FieldPath(FirestoreTest::prop1.name) equalTo "aaa" or (FieldPath(FirestoreTest::count.name) equalTo 2) + } + orQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val andOrQuery = collection + .where { + all( + any( + FieldPath(FirestoreTest::prop1.name) equalTo "aaa", + FieldPath(FirestoreTest::count.name) equalTo 2, + )!!, + FieldPath(FirestoreTest::list.name) contains "a", + ) + } + andOrQuery.assertDocuments(FirestoreTest.serializer(), testOne) + } + + @Test + fun testQueryByDocumentId() = runTestWithFirestoreData { + val fieldQuery = collection + .where { FieldPath.documentId equalTo "one" } + fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) + } + + @Test + fun testQueryByTimestamp() = runTest { + @Serializable + data class DocumentWithTimestamp( + val time: Timestamp, + ) + + val collection = firestore + .collection("testQueryByTimestamp") + + val timestamp = Timestamp.fromMilliseconds(1693262549000.0) + + val pastTimestamp = Timestamp(timestamp.seconds - 60, 12345000) // note: iOS truncates 3 last digits of nanoseconds due to internal conversions + val futureTimestamp = Timestamp(timestamp.seconds + 60, 78910000) + + collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(pastTimestamp)) + collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(futureTimestamp)) + + val equalityQueryResult = collection.where { + FieldPath(DocumentWithTimestamp::time.name) equalTo pastTimestamp + }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() + + assertEquals(setOf(DocumentWithTimestamp(pastTimestamp)), equalityQueryResult) + + val gtQueryResult = collection.where { + FieldPath(DocumentWithTimestamp::time.name) greaterThan timestamp + }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() + + assertEquals(setOf(DocumentWithTimestamp(futureTimestamp)), gtQueryResult) + } + + @Test + fun testStartAfterDocumentSnapshot() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val firstPage = query.limit(2) + + firstPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + val lastDocumentSnapshot = firstPage.get().documents.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.startAfter(lastDocumentSnapshot) + secondPage.assertDocuments(FirestoreTest.serializer(), testThree) + } + + @Test + fun testStartAfterFieldValues() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + query.assertDocuments(FirestoreTest.serializer(), testOne, testTwo, testThree) + + val secondPage = query.startAfter("bbb") + secondPage.assertDocuments(FirestoreTest.serializer(), testThree) + + val encodedQuery = collection + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedSecondPage = encodedQuery.startAfter { + addWithStrategy(NestedObject.serializer(), NestedObject("eee")) + } + encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testThree) + + val multipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val multipleSecondPage = multipleQuery.startAfter(0.0, "aaa") + multipleSecondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val encodedMultipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedMultipleSecondPage = encodedMultipleQuery.startAfter { + add(0.0) + addWithStrategy(NestedObject.serializer(), NestedObject("ddd")) + } + encodedMultipleSecondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + } + + @Test + fun testStartAtDocumentSnapshot() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val firstPage = query.limit(2) + firstPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val lastDocumentSnapshot = firstPage.get().documents.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.startAt(lastDocumentSnapshot) + secondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + } + + @Test + fun testStartAtFieldValues() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val secondPage = query.startAt("bbb") + secondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val encodedQuery = collection + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedSecondPage = encodedQuery.startAt { + addWithStrategy(NestedObject.serializer(), NestedObject("eee")) + } + encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val multipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val multipleSecondPage = multipleQuery.startAt(0.0, "bbb") + multipleSecondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + + val encodedMultipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedMultipleSecondPage = encodedMultipleQuery.startAt { + add(0.0) + addWithStrategy(NestedObject.serializer(), NestedObject("eee")) + } + encodedMultipleSecondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) + } + + @Test + fun testEndBeforeDocumentSnapshot() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val firstPage = query.limit(2) + firstPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val lastDocumentSnapshot = firstPage.get().documents.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.endBefore(lastDocumentSnapshot) + secondPage.assertDocuments(FirestoreTest.serializer(), testOne) + } + + @Test + fun testEndBeforeFieldValues() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val secondPage = query.endBefore("bbb") + secondPage.assertDocuments(FirestoreTest.serializer(), testOne) + + val encodedQuery = collection + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedSecondPage = encodedQuery.endBefore { + addWithStrategy(NestedObject.serializer(), NestedObject("eee")) + } + encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testOne) + + val multipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val multipleSecondPage = multipleQuery.endBefore(0.0, "bbb") + multipleSecondPage.assertDocuments(FirestoreTest.serializer(), testOne) + + val encodedMultipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedMultipleSecondPage = encodedMultipleQuery.endBefore { + add(0.0) + addWithStrategy(NestedObject.serializer(), NestedObject("eee")) + } + encodedMultipleSecondPage.assertDocuments(FirestoreTest.serializer(), testOne) + } + + @Test + fun testEndAtDocumentSnapshot() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val firstPage = query.limit(2) // First 2 results + firstPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val lastDocumentSnapshot = firstPage.get().documents.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.endAt(lastDocumentSnapshot) + secondPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + } + + @Test + fun testEndAtFieldValues() = runTestWithFirestoreData { + val query = collection + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val secondPage = query.endAt("bbb") + secondPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val encodedQuery = collection + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedSecondPage = encodedQuery.endAt { + addWithStrategy(NestedObject.serializer(), NestedObject("eee")) + } + encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) + + val multipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::prop1.name, Direction.ASCENDING) + + val multipleSecondPage = multipleQuery.endAt(0.0, "aaa") + multipleSecondPage.assertDocuments(FirestoreTest.serializer(), testOne) + + val encodedMultipleQuery = collection + .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) + .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) + + val encodedMultipleSecondPage = encodedMultipleQuery.endAt { + add(0.0) + addWithStrategy(NestedObject.serializer(), NestedObject("ddd")) + } + encodedMultipleSecondPage.assertDocuments(FirestoreTest.serializer(), testOne) + } + + private fun runTestWithFirestoreData( + documentOne: FirestoreTest = testOne, + documentTwo: FirestoreTest = testTwo, + documentThree: FirestoreTest = testThree, + block: suspend () -> Unit, + ) = runTest { + try { + setupFirestoreData(documentOne, documentTwo, documentThree) + block() + } finally { + cleanFirestoreData() + } + } + + private suspend fun setupFirestoreData( + documentOne: FirestoreTest = testOne, + documentTwo: FirestoreTest = testTwo, + documentThree: FirestoreTest = testThree, + ) { + firestore.collection(COLLECTION) + .document("one") + .set(FirestoreTest.serializer(), documentOne) + firestore.collection(COLLECTION) + .document("two") + .set(FirestoreTest.serializer(), documentTwo) + firestore.collection(COLLECTION) + .document("three") + .set(FirestoreTest.serializer(), documentThree) + } + + private suspend fun cleanFirestoreData() { + firestore.collection(COLLECTION).document("one").delete() + firestore.collection(COLLECTION).document("two").delete() + firestore.collection(COLLECTION).document("three").delete() + } + + private suspend fun Query.assertDocuments(serializer: KSerializer, vararg expected: T) { + val documents = get().documents + assertEquals(expected.size, documents.size) + documents.forEachIndexed { index, documentSnapshot -> + assertEquals(expected[index], documentSnapshot.data(serializer)) + } + } +} diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt new file mode 100644 index 000000000..b06ac071c --- /dev/null +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt @@ -0,0 +1,220 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.runTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds + +@IgnoreForAndroidUnitTest +class WriteBatchTest : BaseFirebaseFirestoreTest() { + + private val collection get() = firestore + .collection("testServerTestSetBatch") + + @Test + fun testSetBatch() = runTest { + val doc1 = collection + .document("test1") + val doc2 = collection + .document("test2") + val batch = firestore.batch() + batch.set( + documentRef = doc1, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop1", + time = 123.0, + ), + ) + batch.set( + documentRef = doc2, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop2", + time = 456.0, + ), + ) + batch.commit() + + assertEquals("prop1", doc1.get().data(FirestoreTest.serializer()).prop1) + assertEquals("prop2", doc2.get().data(FirestoreTest.serializer()).prop1) + } + + @Test + fun testSetBatchDoesNotEncodeEmptyValues() = runTest { + val doc1 = collection + .document("test1") + val doc2 = collection + .document("test2") + val batch = firestore.batch() + batch.set( + documentRef = doc1, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop1-set", + time = 125.0, + ), + ) + batch.set( + documentRef = doc2, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop2-set", + time = 250.0, + ), + ) + batch.commit() + + assertEquals(125.0, doc1.get().get("time") as Double?) + assertEquals("prop1-set", doc1.get().data(FirestoreTest.serializer()).prop1) + assertEquals(250.0, doc2.get().get("time") as Double?) + assertEquals("prop2-set", doc2.get().data(FirestoreTest.serializer()).prop1) + } + + @Test + fun testUpdateBatch() = runTest { + val doc1 = collection + .document("test1").apply { + set( + FirestoreTest( + prop1 = "prop1", + time = 123.0, + ), + ) + } + val doc2 = collection + .document("test2").apply { + set( + FirestoreTest( + prop1 = "prop2", + time = 456.0, + ), + ) + } + + val batch = firestore.batch() + batch.update( + documentRef = doc1, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop1-updated", + time = 345.0, + ), + ) { + encodeDefaults = false + } + batch.update( + documentRef = doc2, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop2-updated", + time = 567.0, + ), + ) { + encodeDefaults = false + } + batch.commit() + + assertEquals("prop1-updated", doc1.get().data(FirestoreTest.serializer()).prop1) + assertEquals("prop2-updated", doc2.get().data(FirestoreTest.serializer()).prop1) + } + + @Test + fun testUpdateBatchDoesNotEncodeEmptyValues() = runTest { + val doc1 = collection + .document("test1").apply { + set( + FirestoreTest( + prop1 = "prop1", + time = 123.0, + ), + ) + } + val doc2 = collection + .document("test2").apply { + set( + FirestoreTest( + prop1 = "prop2", + time = 456.0, + ), + ) + } + val batch = firestore.batch() + batch.update( + documentRef = doc1, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop1-set", + time = 126.0, + ), + ) { + encodeDefaults = false + } + batch.update( + documentRef = doc2, + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop2-set", + time = 457.0, + ), + ) { + encodeDefaults = false + } + batch.commit() + + assertEquals(126.0, doc1.get().get("time") as Double?) + assertEquals("prop1-set", doc1.get().data(FirestoreTest.serializer()).prop1) + assertEquals(457.0, doc2.get().get("time") as Double?) + assertEquals("prop2-set", doc2.get().data(FirestoreTest.serializer()).prop1) + } + + @Test + fun testUpdateFieldValuesBatch() = runTest { + val doc1 = collection.document("test1").apply { + set( + FirestoreTest( + prop1 = "prop1", + time = 123.0, + duration = 800.milliseconds, + ), + ) + } + + val doc2 = collection.document("test2").apply { + set( + FirestoreTest( + prop1 = "prop2", + time = 456.0, + duration = 700.milliseconds, + ), + ) + } + + val batch = firestore.batch() + batch.update(doc1) { + FirestoreTest::prop1.name to "prop1-updated" + FieldPath(FirestoreTest::optional.name) to "notNull" + FirestoreTest::duration.name.to(DurationAsLongSerializer(), 300.milliseconds) + FieldPath(FirestoreTest::nested.name).to(NestedObject.serializer(), NestedObject("nested")) + } + batch.update(doc2) { + FirestoreTest::prop1.name to "prop2-updated" + FieldPath(FirestoreTest::optional.name) to "alsoNotNull" + FirestoreTest::duration.name.to(DurationAsLongSerializer(), 200.milliseconds) + FieldPath(FirestoreTest::nested.name).to(NestedObject.serializer(), NestedObject("alsoNested")) + } + batch.commit() + + val updatedDoc1 = doc1.get().data(FirestoreTest.serializer()) + assertEquals("prop1-updated", updatedDoc1.prop1) + assertEquals("notNull", updatedDoc1.optional) + assertEquals(300.milliseconds, updatedDoc1.duration) + assertEquals(NestedObject("nested"), updatedDoc1.nested) + + val updatedDoc2 = doc2.get().data(FirestoreTest.serializer()) + assertEquals("prop2-updated", updatedDoc2.prop1) + assertEquals("alsoNotNull", updatedDoc2.optional) + assertEquals(200.milliseconds, updatedDoc2.duration) + assertEquals(NestedObject("alsoNested"), updatedDoc2.nested) + } +} diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 4c727df6a..d55d5dce9 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -8,30 +8,19 @@ import dev.gitlive.firebase.Firebase import dev.gitlive.firebase.FirebaseApp import dev.gitlive.firebase.FirebaseOptions import dev.gitlive.firebase.apps -import dev.gitlive.firebase.internal.decode import dev.gitlive.firebase.initialize import dev.gitlive.firebase.runBlockingTest import dev.gitlive.firebase.runTest -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.withContext import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable -import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.builtins.nullable -import kotlinx.serialization.builtins.serializer -import kotlin.random.Random +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals -import kotlin.test.assertNotNull -import kotlin.test.assertNull -import kotlin.test.assertTrue import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds @@ -45,7 +34,7 @@ expect fun encodedAsMap(encoded: Any?): Map expect fun Map.asEncoded(): Any @IgnoreForAndroidUnitTest -class FirebaseFirestoreTest { +abstract class BaseFirebaseFirestoreTest { @Serializable data class FirestoreTest( @@ -56,12 +45,8 @@ class FirebaseFirestoreTest { val optional: String? = null, val nested: NestedObject? = null, val nestedList: List = emptyList(), - ) - - @Serializable - data class FirestoreTimeTest( - val prop1: String, - val time: BaseTimestamp?, + @Serializable(with = DurationAsLongSerializer::class) + val duration: Duration = Duration.ZERO, ) @Serializable @@ -69,34 +54,15 @@ class FirebaseFirestoreTest { val prop2: String, ) - companion object { - val testOne = FirestoreTest( - "aaa", - 0.0, - 1, - listOf("a", "aa", "aaa"), - "notNull", - NestedObject("ddd"), - listOf(NestedObject("l1"), NestedObject("l2"), NestedObject("l3")), - ) - val testTwo = FirestoreTest( - "bbb", - 0.0, - 2, - listOf("b", "bb", "ccc"), - null, - NestedObject("eee"), - listOf(NestedObject("l2"), NestedObject("l4"), NestedObject("l5")), - ) - val testThree = FirestoreTest( - "ccc", - 1.0, - 3, - listOf("c", "cc", "ccc"), - "notNull", - NestedObject("fff"), - listOf(NestedObject("l6"), NestedObject("l7"), NestedObject("l8")), - ) + class DurationAsLongSerializer : KSerializer { + + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("millisecondsSinceEpoch", PrimitiveKind.LONG) + + override fun serialize(encoder: Encoder, value: Duration) { + encoder.encodeLong(value.inWholeMilliseconds) + } + + override fun deserialize(decoder: Decoder): Duration = decoder.decodeLong().milliseconds } lateinit var firebaseApp: FirebaseApp @@ -133,954 +99,14 @@ class FirebaseFirestoreTest { it.delete() } } +} - @Test - fun testStringOrderBy() = runTest { - setupFirestoreData() - val resultDocs = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1") - .get() - .documents - assertEquals(3, resultDocs.size) - assertEquals("aaa", resultDocs[0].get("prop1")) - assertEquals("bbb", resultDocs[1].get("prop1")) - assertEquals("ccc", resultDocs[2].get("prop1")) - } - - @Test - fun testFieldOrderBy() = runTest { - setupFirestoreData() - - val resultDocs = firestore.collection("testFirestoreQuerying") - .orderBy(FieldPath("prop1")).get().documents - assertEquals(3, resultDocs.size) - assertEquals("aaa", resultDocs[0].get("prop1")) - assertEquals("bbb", resultDocs[1].get("prop1")) - assertEquals("ccc", resultDocs[2].get("prop1")) - } - - @Test - fun testStringOrderByAscending() = runTest { - setupFirestoreData() - - val resultDocs = firestore.collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING).get().documents - assertEquals(3, resultDocs.size) - assertEquals("aaa", resultDocs[0].get("prop1")) - assertEquals("bbb", resultDocs[1].get("prop1")) - assertEquals("ccc", resultDocs[2].get("prop1")) - } - - @Test - fun testFieldOrderByAscending() = runTest { - setupFirestoreData() - - val resultDocs = firestore.collection("testFirestoreQuerying") - .orderBy(FieldPath("prop1"), Direction.ASCENDING).get().documents - assertEquals(3, resultDocs.size) - assertEquals("aaa", resultDocs[0].get("prop1")) - assertEquals("bbb", resultDocs[1].get("prop1")) - assertEquals("ccc", resultDocs[2].get("prop1")) - } - - @Test - fun testStringOrderByDescending() = runTest { - setupFirestoreData() - - val resultDocs = firestore.collection("testFirestoreQuerying") - .orderBy("prop1", Direction.DESCENDING).get().documents - assertEquals(3, resultDocs.size) - assertEquals("ccc", resultDocs[0].get("prop1")) - assertEquals("bbb", resultDocs[1].get("prop1")) - assertEquals("aaa", resultDocs[2].get("prop1")) - } - - @Test - fun testFieldOrderByDescending() = runTest { - setupFirestoreData() - - val resultDocs = firestore.collection("testFirestoreQuerying") - .orderBy(FieldPath("prop1"), Direction.DESCENDING).get().documents - assertEquals(3, resultDocs.size) - assertEquals("ccc", resultDocs[0].get("prop1")) - assertEquals("bbb", resultDocs[1].get("prop1")) - assertEquals("aaa", resultDocs[2].get("prop1")) - } - - @Test - fun testServerTimestampFieldValue() = runTest { - val doc = firestore - .collection("testServerTimestampFieldValue") - .document("test") - doc.set( - FirestoreTimeTest.serializer(), - FirestoreTimeTest("ServerTimestamp", Timestamp(123, 0)), - ) - assertEquals(Timestamp(123, 0), doc.get().get("time", TimestampSerializer)) - - doc.set(FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestamp", Timestamp.ServerTimestamp)) - - assertNotEquals(Timestamp.ServerTimestamp, doc.get().get("time", BaseTimestamp.serializer())) - assertNotEquals(Timestamp.ServerTimestamp, doc.get().data(FirestoreTimeTest.serializer()).time) - } - - @Test - fun testServerTimestampBehaviorNone() = runTest { - val doc = firestore - .collection("testServerTimestampBehaviorNone") - .document("test${Random.nextInt()}") - - val deferredPendingWritesSnapshot = async { - doc.snapshots.filter { it.exists }.first() - } - nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot - - doc.set( - FirestoreTimeTest.serializer(), - FirestoreTimeTest("ServerTimestampBehavior", Timestamp.ServerTimestamp), - ) - - val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() - assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) - assertNull(pendingWritesSnapshot.get("time", BaseTimestamp.serializer().nullable, serverTimestampBehavior = ServerTimestampBehavior.NONE)) - } - - @Test - fun testSetBatch() = runTest { - val doc = firestore - .collection("testServerTestSetBatch") - .document("test") - val batch = firestore.batch() - batch.set( - documentRef = doc, - strategy = FirestoreTest.serializer(), - data = FirestoreTest( - prop1 = "prop1", - time = 123.0, - ), - ) - batch.commit() - - assertEquals("prop1", doc.get().data(FirestoreTest.serializer()).prop1) - } - - @Test - fun testServerTimestampBehaviorEstimate() = runTest { - val doc = firestore - .collection("testServerTimestampBehaviorEstimate") - .document("test${Random.nextInt()}") - - val deferredPendingWritesSnapshot = async { - doc.snapshots.filter { it.exists }.first() - } - nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot - - doc.set(FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestampBehavior", Timestamp.ServerTimestamp)) - - val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() - assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) - assertNotNull(pendingWritesSnapshot.get("time", ServerTimestampBehavior.ESTIMATE)) - assertNotEquals(Timestamp.ServerTimestamp, pendingWritesSnapshot.data(FirestoreTimeTest.serializer(), serverTimestampBehavior = ServerTimestampBehavior.ESTIMATE).time) - } - - @Test - fun testServerTimestampBehaviorPrevious() = runTest { - val doc = firestore - .collection("testServerTimestampBehaviorPrevious") - .document("test${Random.nextInt()}") - - val deferredPendingWritesSnapshot = async { - doc.snapshots.filter { it.exists }.first() - } - nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot - - doc.set(FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestampBehavior", Timestamp.ServerTimestamp)) - - val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() - assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) - assertNull(pendingWritesSnapshot.get("time", BaseTimestamp.serializer().nullable, serverTimestampBehavior = ServerTimestampBehavior.PREVIOUS)) - } - - @Test - fun testDocumentAutoId() = runTest { - val doc = firestore - .collection("testDocumentAutoId") - .document - - doc.set(FirestoreTest.serializer(), FirestoreTest("AutoId")) - - val resultDoc = firestore - .collection("testDocumentAutoId") - .document(doc.id) - .get() - - assertEquals(true, resultDoc.exists) - assertEquals("AutoId", resultDoc.get("prop1")) - } - - @Test - fun testStartAfterDocumentSnapshot() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.limit(2).get().documents // First 2 results - assertEquals(2, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - - val lastDocumentSnapshot = firstPage.lastOrNull() - assertNotNull(lastDocumentSnapshot) - - val secondPage = query.startAfter(lastDocumentSnapshot).get().documents - assertEquals(1, secondPage.size) - assertEquals("ccc", secondPage[0].get("prop1")) - } - - @Test - fun testStartAfterFieldValues() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.get().documents - assertEquals(3, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - assertEquals("ccc", firstPage[2].get("prop1")) - - val secondPage = query.startAfter("bbb").get().documents - assertEquals(1, secondPage.size) - assertEquals("ccc", secondPage[0].get("prop1")) - } - - @Test - fun testStartAtDocumentSnapshot() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.limit(2).get().documents // First 2 results - assertEquals(2, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - - val lastDocumentSnapshot = firstPage.lastOrNull() - assertNotNull(lastDocumentSnapshot) - - val secondPage = query.startAt(lastDocumentSnapshot).get().documents - assertEquals(2, secondPage.size) - assertEquals("bbb", secondPage[0].get("prop1")) - assertEquals("ccc", secondPage[1].get("prop1")) - } - - @Test - fun testStartAtFieldValues() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.get().documents // First 2 results - assertEquals(3, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - assertEquals("ccc", firstPage[2].get("prop1")) - - val secondPage = query.startAt("bbb").get().documents - assertEquals(2, secondPage.size) - assertEquals("bbb", secondPage[0].get("prop1")) - assertEquals("ccc", secondPage[1].get("prop1")) - } - - @Test - fun testEndBeforeDocumentSnapshot() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.limit(2).get().documents // First 2 results - assertEquals(2, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - - val lastDocumentSnapshot = firstPage.lastOrNull() - assertNotNull(lastDocumentSnapshot) - - val secondPage = query.endBefore(lastDocumentSnapshot).get().documents - assertEquals(1, secondPage.size) - assertEquals("aaa", secondPage[0].get("prop1")) - } - - @Test - fun testEndBeforeFieldValues() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.get().documents - assertEquals(3, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - assertEquals("ccc", firstPage[2].get("prop1")) - - val secondPage = query.endBefore("bbb").get().documents - assertEquals(1, secondPage.size) - assertEquals("aaa", secondPage[0].get("prop1")) - } - - @Test - fun testEndAtDocumentSnapshot() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.limit(2).get().documents // First 2 results - assertEquals(2, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - - val lastDocumentSnapshot = firstPage.lastOrNull() - assertNotNull(lastDocumentSnapshot) - - val secondPage = query.endAt(lastDocumentSnapshot).get().documents - assertEquals(2, secondPage.size) - assertEquals("aaa", secondPage[0].get("prop1")) - assertEquals("bbb", secondPage[1].get("prop1")) - } - - @Test - fun testEndAtFieldValues() = runTest { - setupFirestoreData() - val query = firestore - .collection("testFirestoreQuerying") - .orderBy("prop1", Direction.ASCENDING) - - val firstPage = query.get().documents // First 2 results - assertEquals(3, firstPage.size) - assertEquals("aaa", firstPage[0].get("prop1")) - assertEquals("bbb", firstPage[1].get("prop1")) - assertEquals("ccc", firstPage[2].get("prop1")) - - val secondPage = query.endAt("bbb").get().documents - assertEquals(2, secondPage.size) - assertEquals("aaa", secondPage[0].get("prop1")) - assertEquals("bbb", secondPage[1].get("prop1")) - } - - @Test - fun testIncrementFieldValue() = runTest { - val doc = firestore - .collection("testFirestoreIncrementFieldValue") - .document("test1") - - doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", count = 0)) - val dataBefore = doc.get().data(FirestoreTest.serializer()) - assertEquals(0, dataBefore.count) - - doc.update("count" to FieldValue.increment(5)) - val dataAfter = doc.get().data(FirestoreTest.serializer()) - assertEquals(5, dataAfter.count) - } - - @Test - fun testArrayUnion() = runTest { - val doc = firestore - .collection("testFirestoreArrayUnion") - .document("test1") - - doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", list = listOf("first"))) - val dataBefore = doc.get().data(FirestoreTest.serializer()) - assertEquals(listOf("first"), dataBefore.list) - - doc.update("list" to FieldValue.arrayUnion("second")) - val dataAfter = doc.get().data(FirestoreTest.serializer()) - assertEquals(listOf("first", "second"), dataAfter.list) - } - - @Test - fun testArrayRemove() = runTest { - val doc = firestore - .collection("testFirestoreArrayRemove") - .document("test1") - - doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", list = listOf("first", "second"))) - val dataBefore = doc.get().data(FirestoreTest.serializer()) - assertEquals(listOf("first", "second"), dataBefore.list) - - doc.update("list" to FieldValue.arrayRemove("second")) - val dataAfter = doc.get().data(FirestoreTest.serializer()) - assertEquals(listOf("first"), dataAfter.list) - } - - @Test - fun testSetBatchDoesNotEncodeEmptyValues() = runTest { - val doc = firestore - .collection("testServerTestSetBatch") - .document("test") - val batch = firestore.batch() - batch.set( - documentRef = doc, - strategy = FirestoreTest.serializer(), - data = FirestoreTest( - prop1 = "prop1-set", - time = 125.0, - ), - ) - batch.commit() - - assertEquals(125.0, doc.get().get("time") as Double?) - assertEquals("prop1-set", doc.get().data(FirestoreTest.serializer()).prop1) - } - - @Test - fun testUpdateBatch() = runTest { - val doc = firestore - .collection("testServerTestSetBatch") - .document("test").apply { - set( - FirestoreTest( - prop1 = "prop1", - time = 123.0, - ), - ) - } - - val batch = firestore.batch() - batch.update( - documentRef = doc, - strategy = FirestoreTest.serializer(), - data = FirestoreTest( - prop1 = "prop1-updated", - time = 123.0, - ), - ) { - encodeDefaults = false - } - batch.commit() - - assertEquals("prop1-updated", doc.get().data(FirestoreTest.serializer()).prop1) - } - - @Test - fun testUpdateBatchDoesNotEncodeEmptyValues() = runTest { - val doc = firestore - .collection("testServerTestSetBatch") - .document("test").apply { - set( - FirestoreTest( - prop1 = "prop1", - time = 123.0, - ), - ) - } - val batch = firestore.batch() - batch.update( - documentRef = doc, - strategy = FirestoreTest.serializer(), - data = FirestoreTest( - prop1 = "prop1-set", - time = 126.0, - ), - ) { - encodeDefaults = false - } - batch.commit() - - assertEquals(126.0, doc.get().get("time") as Double?) - assertEquals("prop1-set", doc.get().data(FirestoreTest.serializer()).prop1) - } - - @Test - fun testLegacyDoubleTimestamp() = runTest { - @Serializable - data class DoubleTimestamp( - @Serializable(with = DoubleAsTimestampSerializer::class) - val time: Double?, - ) - - val doc = firestore - .collection("testLegacyDoubleTimestamp") - .document("test${Random.nextInt()}") - - val deferredPendingWritesSnapshot = async { - doc.snapshots.filter { it.exists }.first() - } - nonSkippedDelay(100.milliseconds) // makes possible to catch pending writes snapshot - - doc.set(DoubleTimestamp.serializer(), DoubleTimestamp(DoubleAsTimestampSerializer.SERVER_TIMESTAMP)) - - val pendingWritesSnapshot = deferredPendingWritesSnapshot.await() - assertTrue(pendingWritesSnapshot.metadata.hasPendingWrites) - assertNotNull(pendingWritesSnapshot.get("time", DoubleAsTimestampSerializer, serverTimestampBehavior = ServerTimestampBehavior.ESTIMATE)) - assertNotEquals(DoubleAsTimestampSerializer.SERVER_TIMESTAMP, pendingWritesSnapshot.data(DoubleTimestamp.serializer(), serverTimestampBehavior = ServerTimestampBehavior.ESTIMATE).time) - } - - @Test - fun testLegacyDoubleTimestampWriteNewFormatRead() = runTest { - @Serializable - data class LegacyDocument( - @Serializable(with = DoubleAsTimestampSerializer::class) - val time: Double, - ) - - @Serializable - data class NewDocument( - val time: Timestamp, - ) - - val doc = firestore - .collection("testLegacyDoubleTimestampEncodeDecode") - .document("testLegacy") - - val ms = 12345678.0 - - doc.set(LegacyDocument.serializer(), LegacyDocument(time = ms)) - - val fetched: NewDocument = doc.get().data(NewDocument.serializer()) - assertEquals(ms, fetched.time.toMilliseconds()) - } - - @Test - fun testQueryByTimestamp() = runTest { - @Serializable - data class DocumentWithTimestamp( - val time: Timestamp, - ) - - val collection = firestore - .collection("testQueryByTimestamp") - - val timestamp = Timestamp.fromMilliseconds(1693262549000.0) - - val pastTimestamp = Timestamp(timestamp.seconds - 60, 12345000) // note: iOS truncates 3 last digits of nanoseconds due to internal conversions - val futureTimestamp = Timestamp(timestamp.seconds + 60, 78910000) - - collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(pastTimestamp)) - collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(futureTimestamp)) - - val equalityQueryResult = collection.where { - FieldPath(DocumentWithTimestamp::time.name) equalTo pastTimestamp - }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() - - assertEquals(setOf(DocumentWithTimestamp(pastTimestamp)), equalityQueryResult) - - val gtQueryResult = collection.where { - FieldPath(DocumentWithTimestamp::time.name) greaterThan timestamp - }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() - - assertEquals(setOf(DocumentWithTimestamp(futureTimestamp)), gtQueryResult) - } - - @Test - fun testGeoPointSerialization() = runTest { - @Serializable - data class DataWithGeoPoint(val geoPoint: GeoPoint) - - fun getDocument() = firestore.collection("geoPointSerialization") - .document("geoPointSerialization") - - val data = DataWithGeoPoint(GeoPoint(12.34, 56.78)) - // store geo point - getDocument().set(DataWithGeoPoint.serializer(), data) - // restore data - val savedData = getDocument().get().data(DataWithGeoPoint.serializer()) - assertEquals(data.geoPoint, savedData.geoPoint) - - // update data - val updatedData = DataWithGeoPoint(GeoPoint(87.65, 43.21)) - getDocument().update(FieldPath(DataWithGeoPoint::geoPoint.name) to updatedData.geoPoint) - // verify update - val updatedSavedData = getDocument().get().data(DataWithGeoPoint.serializer()) - assertEquals(updatedData.geoPoint, updatedSavedData.geoPoint) - } - - @Test - fun testDocumentReferenceSerialization() = runTest { - @Serializable - data class DataWithDocumentReference( - val documentReference: DocumentReference, - ) - - fun getCollection() = firestore.collection("documentReferenceSerialization") - fun getDocument() = getCollection() - .document("documentReferenceSerialization") - val documentRef1 = getCollection().document("refDoc1").apply { - set(mapOf("value" to 1)) - } - val documentRef2 = getCollection().document("refDoc2").apply { - set(mapOf("value" to 2)) - } - - val data = DataWithDocumentReference(documentRef1) - // store reference - getDocument().set(DataWithDocumentReference.serializer(), data) - // restore data - val savedData = getDocument().get().data(DataWithDocumentReference.serializer()) - assertEquals(data.documentReference.path, savedData.documentReference.path) - - // update data - val updatedData = DataWithDocumentReference(documentRef2) - getDocument().update(fieldsAndValuesBuilder = { - FieldPath(DataWithDocumentReference::documentReference.name).to( - DocumentReferenceSerializer, - updatedData.documentReference, - ) - }) - // verify update - val updatedSavedData = getDocument().get().data(DataWithDocumentReference.serializer()) - assertEquals(updatedData.documentReference.path, updatedSavedData.documentReference.path) - } - - @Serializable - data class TestDataWithDocumentReference( - val uid: String, - val reference: DocumentReference, - val optionalReference: DocumentReference?, - ) - - @Serializable - data class TestDataWithOptionalDocumentReference( - val optionalReference: DocumentReference?, - ) - - @Test - fun encodeDocumentReference() = runTest { - val doc = firestore.document("a/b") - val item = TestDataWithDocumentReference("123", doc, doc) - val encoded = encodedAsMap( - encode(item) { - encodeDefaults = false - }, - ) - assertEquals("123", encoded["uid"]) - assertEquals(doc.nativeValue, encoded["reference"]) - assertEquals(doc.nativeValue, encoded["optionalReference"]) - } - - @Test - fun encodeNullDocumentReference() = runTest { - val item = TestDataWithOptionalDocumentReference(null) - val encoded = encodedAsMap( - encode(item) { - encodeDefaults = false - }, - ) - assertNull(encoded["optionalReference"]) - } - - @Test - fun decodeDocumentReference() = runTest { - val doc = firestore.document("a/b") - val obj = mapOf( - "uid" to "123", - "reference" to doc.nativeValue, - "optionalReference" to doc.nativeValue, - ).asEncoded() - val decoded: TestDataWithDocumentReference = decode(obj) - assertEquals("123", decoded.uid) - assertEquals(doc.path, decoded.reference.path) - assertEquals(doc.path, decoded.optionalReference?.path) - } - - @Test - fun decodeNullDocumentReference() = runTest { - val obj = mapOf("optionalReference" to null).asEncoded() - val decoded: TestDataWithOptionalDocumentReference = decode(obj) - assertNull(decoded.optionalReference?.path) - } - - @Test - fun testFieldValuesOps() = runTest { - @Serializable - data class TestData(val values: List) - fun getDocument() = firestore.collection("fieldValuesOps") - .document("fieldValuesOps") - - val data = TestData(listOf(1)) - // store - getDocument().set(TestData.serializer(), data) - // append & verify - getDocument().update(FieldPath(TestData::values.name) to FieldValue.arrayUnion(2)) - - var savedData = getDocument().get().data(TestData.serializer()) - assertEquals(listOf(1, 2), savedData.values) - - // remove & verify - getDocument().update(FieldPath(TestData::values.name) to FieldValue.arrayRemove(1)) - savedData = getDocument().get().data(TestData.serializer()) - assertEquals(listOf(2), savedData.values) - - val list = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) - assertEquals(listOf(2), list) - // delete & verify - getDocument().update(FieldPath(TestData::values.name) to FieldValue.delete) - val deletedList = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) - assertNull(deletedList) - } - - @Test - fun testQueryEqualTo() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "prop1" equalTo testOne.prop1 } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::prop1.name) equalTo testTwo.prop1 } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testTwo) - - val nullableQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::optional.name).isNull } - - nullableQuery.assertDocuments(FirestoreTest.serializer(), testTwo) - } - - @Test - fun testQueryNotEqualTo() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "prop1" notEqualTo testOne.prop1 } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::prop1.name) notEqualTo testTwo.prop1 } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) - - val nullableQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::optional.name).isNotNull } - - nullableQuery.assertDocuments(FirestoreTest.serializer(), testOne, testThree) - } - - @Test - fun testQueryLessThan() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "count" lessThan testThree.count } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::count.name) lessThan testTwo.count } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testOne) - } - - @Test - fun testQueryGreaterThan() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "count" greaterThan testOne.count } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::count.name) greaterThan testTwo.count } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) - } - - @Test - fun testQueryLessThanOrEqualTo() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "count" lessThanOrEqualTo testOne.count } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::count.name) lessThanOrEqualTo testTwo.count } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) - } - - @Test - fun testQueryGreaterThanOrEqualTo() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "count" greaterThanOrEqualTo testThree.count } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testThree) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::count.name) greaterThanOrEqualTo testTwo.count } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) - } - - @Test - fun testQueryArrayContains() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "list" contains "a" } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::list.name) contains "ccc" } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testThree, testTwo) - } - - @Test - fun testQueryArrayContainsAny() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "list" containsAny listOf("a", "b") } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::list.name) containsAny listOf("c", "d") } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) - } - - @Test - fun testQueryInArray() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "prop1" inArray listOf("aaa", "bbb") } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::prop1.name) inArray listOf("ccc", "ddd") } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) - } - - @Test - fun testQueryNotInArray() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { "prop1" notInArray listOf("aaa", "bbb") } - - fieldQuery.assertDocuments(FirestoreTest.serializer(), testThree) - - val pathQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath(FirestoreTest::prop1.name) notInArray listOf("ccc", "ddd") } - - pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) - } - - @Test - fun testCompoundQuery() = runTest { - setupFirestoreData() - - val andQuery = firestore - .collection("testFirestoreQuerying") - .where { - FieldPath(FirestoreTest::prop1.name) inArray listOf("aaa", "bbb") and (FieldPath(FirestoreTest::count.name) equalTo 1) - } - andQuery.assertDocuments(FirestoreTest.serializer(), testOne) - - val orQuery = firestore - .collection("testFirestoreQuerying") - .where { - FieldPath(FirestoreTest::prop1.name) equalTo "aaa" or (FieldPath(FirestoreTest::count.name) equalTo 2) - } - orQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) - - val andOrQuery = firestore - .collection("testFirestoreQuerying") - .where { - all( - any( - FieldPath(FirestoreTest::prop1.name) equalTo "aaa", - FieldPath(FirestoreTest::count.name) equalTo 2, - )!!, - FieldPath(FirestoreTest::list.name) contains "a", - ) - } - andOrQuery.assertDocuments(FirestoreTest.serializer(), testOne) - } - - @Test - fun testQueryByDocumentId() = runTest { - setupFirestoreData() - - val fieldQuery = firestore - .collection("testFirestoreQuerying") - .where { FieldPath.documentId equalTo "one" } - fieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) - } +@IgnoreForAndroidUnitTest +class FirebaseFirestoreTest : BaseFirebaseFirestoreTest() { @Test fun testMultiple() = runTest { Firebase.firestore(firebaseApp).disableNetwork() Firebase.firestore(firebaseApp).enableNetwork() } - - private suspend fun setupFirestoreData( - documentOne: FirestoreTest = testOne, - documentTwo: FirestoreTest = testTwo, - documentThree: FirestoreTest = testThree, - ) { - firestore.collection("testFirestoreQuerying") - .document("one") - .set(FirestoreTest.serializer(), documentOne) - firestore.collection("testFirestoreQuerying") - .document("two") - .set(FirestoreTest.serializer(), documentTwo) - firestore.collection("testFirestoreQuerying") - .document("three") - .set(FirestoreTest.serializer(), documentThree) - } - - private suspend fun Query.assertDocuments(serializer: KSerializer, vararg expected: T) { - val documents = get().documents - assertEquals(expected.size, documents.size) - documents.forEachIndexed { index, documentSnapshot -> - assertEquals(expected[index], documentSnapshot.data(serializer)) - } - } - - private suspend fun nonSkippedDelay(timeout: Duration) = withContext(Dispatchers.Default) { - delay(timeout) - } } From 9464afc095ed72e4696c025da246f756278f8234 Mon Sep 17 00:00:00 2001 From: Andrew Reed Date: Mon, 2 Sep 2024 21:00:32 +0100 Subject: [PATCH 29/33] Added get reference from url --- .../kotlin/dev/gitlive/firebase/storage/storage.kt | 2 ++ .../kotlin/dev/gitlive/firebase/storage/storage.kt | 10 ++++++++++ .../kotlin/dev/gitlive/firebase/storage/storage.kt | 2 ++ .../kotlin/dev/gitlive/firebase/storage/storage.kt | 2 ++ .../kotlin/dev/gitlive/firebase/storage/storage.jvm.kt | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/firebase-storage/src/androidMain/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/androidMain/kotlin/dev/gitlive/firebase/storage/storage.kt index 8d435afed..41c906c45 100644 --- a/firebase-storage/src/androidMain/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/androidMain/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -55,6 +55,8 @@ public actual class FirebaseStorage(internal val android: com.google.firebase.st public actual val reference: StorageReference get() = StorageReference(android.reference) public actual fun reference(location: String): StorageReference = StorageReference(android.getReference(location)) + + public actual fun getReferenceFromUrl(fullUrl: String): StorageReference = StorageReference(android.getReferenceFromUrl(fullUrl)) } public val StorageReference.android: com.google.firebase.storage.StorageReference get() = android diff --git a/firebase-storage/src/commonMain/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/commonMain/kotlin/dev/gitlive/firebase/storage/storage.kt index 8485adc51..57d311fed 100644 --- a/firebase-storage/src/commonMain/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/commonMain/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -86,6 +86,16 @@ public expect class FirebaseStorage { * @return An instance of [StorageReference] at the given child path. */ public fun reference(location: String): StorageReference + + /** + * Creates a [StorageReference] given a gs:// or https:// URL pointing to a Firebase Storage location. + * + * @param fullUrl A gs:// or http[s]:// URL used to initialize the reference. For example, you can pass + * in a download URL retrieved from getDownloadUrl or the uri retrieved from toString An error is + * thrown if fullUrl is not associated with the FirebaseApp used to initialize this FirebaseStorage. + * @return An instance of [StorageReference] at the given url. + */ + public fun getReferenceFromUrl(fullUrl: String): StorageReference } @Deprecated("Deprecated to use Kotlin Duration", replaceWith = ReplaceWith("maxOperationRetryTime")) diff --git a/firebase-storage/src/iosMain/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/iosMain/kotlin/dev/gitlive/firebase/storage/storage.kt index 0a0c1afab..46dcbe97e 100644 --- a/firebase-storage/src/iosMain/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/iosMain/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -67,6 +67,8 @@ public actual class FirebaseStorage(internal val ios: FIRStorage) { public actual val reference: StorageReference get() = StorageReference(ios.reference()) public actual fun reference(location: String): StorageReference = StorageReference(ios.referenceWithPath(location)) + + public actual fun getReferenceFromUrl(fullUrl: String): StorageReference = StorageReference(ios.referenceForURL(fullUrl)) } public val StorageReference.ios: FIRStorageReference get() = ios diff --git a/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt b/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt index 14a7897b3..5337601ae 100644 --- a/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt +++ b/firebase-storage/src/jsMain/kotlin/dev/gitlive/firebase/storage/storage.kt @@ -51,6 +51,8 @@ public actual class FirebaseStorage(internal val js: dev.gitlive.firebase.storag public actual val reference: StorageReference get() = StorageReference(ref(js)) public actual fun reference(location: String): StorageReference = rethrow { StorageReference(ref(js, location)) } + + public actual fun getReferenceFromUrl(fullUrl: String): StorageReference = rethrow { StorageReference(ref(js, fullUrl)) } } public val StorageReference.js get() = js diff --git a/firebase-storage/src/jvmMain/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt b/firebase-storage/src/jvmMain/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt index 9d4f16ab8..c3674a728 100644 --- a/firebase-storage/src/jvmMain/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt +++ b/firebase-storage/src/jvmMain/kotlin/dev/gitlive/firebase/storage/storage.jvm.kt @@ -37,6 +37,10 @@ public actual class FirebaseStorage { public actual fun reference(location: String): StorageReference { TODO("Not yet implemented") } + + public actual fun getReferenceFromUrl(fullUrl: String): StorageReference { + TODO("Not yet implemented") + } } public actual class StorageReference { From 80f0ba0280cfc6f9818404ee178ed8815c34adf6 Mon Sep 17 00:00:00 2001 From: Andrew Reed Date: Mon, 2 Sep 2024 21:16:10 +0100 Subject: [PATCH 30/33] adjusted firebase storage api --- firebase-storage/api/android/firebase-storage.api | 1 + firebase-storage/api/jvm/firebase-storage.api | 1 + 2 files changed, 2 insertions(+) diff --git a/firebase-storage/api/android/firebase-storage.api b/firebase-storage/api/android/firebase-storage.api index 4715f8dcf..3613f5aab 100644 --- a/firebase-storage/api/android/firebase-storage.api +++ b/firebase-storage/api/android/firebase-storage.api @@ -13,6 +13,7 @@ public final class dev/gitlive/firebase/storage/FirebaseStorage { public final fun getMaxOperationRetryTime-UwyO8pc ()J public final fun getMaxUploadRetryTime-UwyO8pc ()J public final fun getReference ()Ldev/gitlive/firebase/storage/StorageReference; + public final fun getReferenceFromUrl (Ljava/lang/String;)Ldev/gitlive/firebase/storage/StorageReference; public final fun reference (Ljava/lang/String;)Ldev/gitlive/firebase/storage/StorageReference; public final fun setMaxOperationRetryTime-LRDsOJo (J)V public final fun setMaxUploadRetryTime-LRDsOJo (J)V diff --git a/firebase-storage/api/jvm/firebase-storage.api b/firebase-storage/api/jvm/firebase-storage.api index e94fb4ab9..eaa50149c 100644 --- a/firebase-storage/api/jvm/firebase-storage.api +++ b/firebase-storage/api/jvm/firebase-storage.api @@ -11,6 +11,7 @@ public final class dev/gitlive/firebase/storage/FirebaseStorage { public final fun getMaxOperationRetryTime-UwyO8pc ()J public final fun getMaxUploadRetryTime-UwyO8pc ()J public final fun getReference ()Ldev/gitlive/firebase/storage/StorageReference; + public final fun getReferenceFromUrl (Ljava/lang/String;)Ldev/gitlive/firebase/storage/StorageReference; public final fun reference (Ljava/lang/String;)Ldev/gitlive/firebase/storage/StorageReference; public final fun setMaxOperationRetryTime-LRDsOJo (J)V public final fun setMaxUploadRetryTime-LRDsOJo (J)V From 90f870c68501dd99bfe4e1d36d33947dc7a48c20 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 2 Sep 2024 21:50:11 +0200 Subject: [PATCH 31/33] Added several tests to stabilize tests --- README.md | 9 + .../firestore/DocumentReferenceTest.kt | 215 ++++++++++-------- .../firebase/firestore/FirestoreSourceTest.kt | 66 +++--- .../gitlive/firebase/firestore/QueryTest.kt | 41 ++-- .../firebase/firestore/TransactionTest.kt | 53 +++++ .../firebase/firestore/WriteBatchTest.kt | 128 +++++------ .../gitlive/firebase/firestore/firestore.kt | 11 +- .../firebase/firestore/ContextSwitchTest.kt | 50 ++-- 8 files changed, 339 insertions(+), 234 deletions(-) create mode 100644 firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/TransactionTest.kt diff --git a/README.md b/README.md index 842a36cb7..675f6e2e0 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,15 @@ citiesRef.where { } ``` +Similar methods exist for `update` methods in the Firestore module: + +```kotlin +documentRef.update { + "field" to "value" + "otherField".to(IntAsStringSerializer(), 1) +} +``` +

Operator overloading

In cases where it makes sense, such as Firebase Functions HTTPS Callable, operator overloading is used: diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt index 446dbb4ab..d58024788 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceTest.kt @@ -2,6 +2,7 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.internal.decode import dev.gitlive.firebase.runTest +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.delay @@ -90,10 +91,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testServerTimestampFieldValue() = runTest { - val doc = firestore + fun testServerTimestampFieldValue() = testDocument( + firestore .collection("testServerTimestampFieldValue") - .document("test") + .document("test"), + ) { doc -> doc.set( FirestoreTimeTest.serializer(), FirestoreTimeTest("ServerTimestamp", Timestamp(123, 0)), @@ -107,11 +109,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testServerTimestampBehaviorNone() = runTest { - val doc = firestore + fun testServerTimestampBehaviorNone() = testDocument( + firestore .collection("testServerTimestampBehaviorNone") - .document("test${Random.nextInt()}") - + .document("test${Random.nextInt()}"), + ) { doc -> val deferredPendingWritesSnapshot = async { doc.snapshots.filter { it.exists }.first() } @@ -128,11 +130,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testServerTimestampBehaviorEstimate() = runTest { - val doc = firestore + fun testServerTimestampBehaviorEstimate() = testDocument( + firestore .collection("testServerTimestampBehaviorEstimate") - .document("test${Random.nextInt()}") - + .document("test${Random.nextInt()}"), + ) { doc -> val deferredPendingWritesSnapshot = async { doc.snapshots.filter { it.exists }.first() } @@ -147,11 +149,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testServerTimestampBehaviorPrevious() = runTest { - val doc = firestore + fun testServerTimestampBehaviorPrevious() = testDocument( + firestore .collection("testServerTimestampBehaviorPrevious") - .document("test${Random.nextInt()}") - + .document("test${Random.nextInt()}"), + ) { doc -> val deferredPendingWritesSnapshot = async { doc.snapshots.filter { it.exists }.first() } @@ -165,10 +167,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testDocumentAutoId() = runTest { - val doc = firestore + fun testDocumentAutoId() = testDocument( + firestore .collection("testDocumentAutoId") - .document + .document, + ) { doc -> doc.set(FirestoreTest.serializer(), FirestoreTest("AutoId")) @@ -182,12 +185,20 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testUpdateValues() = runTest { - val doc = firestore + fun testUpdateValues() = testDocument( + firestore .collection("testFirestoreUpdateMultipleValues") - .document("test1") - - doc.set(FirestoreTest.serializer(), FirestoreTest("property", count = 0, nested = NestedObject("nested"), duration = 600.milliseconds)) + .document("test1"), + ) { doc -> + doc.set( + FirestoreTest.serializer(), + FirestoreTest( + "property", + count = 0, + nested = NestedObject("nested"), + duration = 600.milliseconds, + ), + ) val dataBefore = doc.get().data(FirestoreTest.serializer()) assertEquals(0, dataBefore.count) assertNull(dataBefore.optional) @@ -197,8 +208,14 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { doc.update { FirestoreTest::count.name to 5 FieldPath(FirestoreTest::optional.name) to "notNull" - FirestoreTest::nested.name.to(NestedObject.serializer(), NestedObject("newProperty")) - FieldPath(FirestoreTest::duration.name).to(DurationAsLongSerializer(), 700.milliseconds) + FirestoreTest::nested.name.to( + NestedObject.serializer(), + NestedObject("newProperty"), + ) + FieldPath(FirestoreTest::duration.name).to( + DurationAsIntSerializer(), + 700.milliseconds, + ) } val dataAfter = doc.get().data(FirestoreTest.serializer()) assertEquals(5, dataAfter.count) @@ -208,11 +225,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testIncrementFieldValue() = runTest { - val doc = firestore + fun testIncrementFieldValue() = testDocument( + firestore .collection("testFirestoreIncrementFieldValue") - .document("test1") - + .document("test1"), + ) { doc -> doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", count = 0)) val dataBefore = doc.get().data(FirestoreTest.serializer()) assertEquals(0, dataBefore.count) @@ -223,11 +240,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testArrayUnion() = runTest { - val doc = firestore + fun testArrayUnion() = testDocument( + firestore .collection("testFirestoreArrayUnion") - .document("test1") - + .document("test1"), + ) { doc -> doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", list = listOf("first"))) val dataBefore = doc.get().data(FirestoreTest.serializer()) assertEquals(listOf("first"), dataBefore.list) @@ -238,11 +255,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testArrayRemove() = runTest { - val doc = firestore + fun testArrayRemove() = testDocument( + firestore .collection("testFirestoreArrayRemove") - .document("test1") - + .document("test1"), + ) { doc -> doc.set(FirestoreTest.serializer(), FirestoreTest("increment1", list = listOf("first", "second"))) val dataBefore = doc.get().data(FirestoreTest.serializer()) assertEquals(listOf("first", "second"), dataBefore.list) @@ -253,17 +270,17 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testLegacyDoubleTimestamp() = runTest { + fun testLegacyDoubleTimestamp() = testDocument( + firestore + .collection("testLegacyDoubleTimestamp") + .document("test${Random.nextInt()}"), + ) { doc -> @Serializable data class DoubleTimestamp( @Serializable(with = DoubleAsTimestampSerializer::class) val time: Double?, ) - val doc = firestore - .collection("testLegacyDoubleTimestamp") - .document("test${Random.nextInt()}") - val deferredPendingWritesSnapshot = async { doc.snapshots.filter { it.exists }.first() } @@ -278,7 +295,11 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testLegacyDoubleTimestampWriteNewFormatRead() = runTest { + fun testLegacyDoubleTimestampWriteNewFormatRead() = testDocument( + firestore + .collection("testLegacyDoubleTimestampEncodeDecode") + .document("testLegacy"), + ) { doc -> @Serializable data class LegacyDocument( @Serializable(with = DoubleAsTimestampSerializer::class) @@ -290,10 +311,6 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { val time: Timestamp, ) - val doc = firestore - .collection("testLegacyDoubleTimestampEncodeDecode") - .document("testLegacy") - val ms = 12345678.0 doc.set(LegacyDocument.serializer(), LegacyDocument(time = ms)) @@ -303,25 +320,25 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { } @Test - fun testGeoPointSerialization() = runTest { + fun testGeoPointSerialization() = testDocument( + firestore.collection("geoPointSerialization") + .document("geoPointSerialization"), + ) { doc -> @Serializable data class DataWithGeoPoint(val geoPoint: GeoPoint) - fun getDocument() = firestore.collection("geoPointSerialization") - .document("geoPointSerialization") - val data = DataWithGeoPoint(GeoPoint(12.34, 56.78)) // store geo point - getDocument().set(DataWithGeoPoint.serializer(), data) + doc.set(DataWithGeoPoint.serializer(), data) // restore data - val savedData = getDocument().get().data(DataWithGeoPoint.serializer()) + val savedData = doc.get().data(DataWithGeoPoint.serializer()) assertEquals(data.geoPoint, savedData.geoPoint) // update data val updatedData = DataWithGeoPoint(GeoPoint(87.65, 43.21)) - getDocument().update(FieldPath(DataWithGeoPoint::geoPoint.name) to updatedData.geoPoint) + doc.update(FieldPath(DataWithGeoPoint::geoPoint.name) to updatedData.geoPoint) // verify update - val updatedSavedData = getDocument().get().data(DataWithGeoPoint.serializer()) + val updatedSavedData = doc.get().data(DataWithGeoPoint.serializer()) assertEquals(updatedData.geoPoint, updatedSavedData.geoPoint) } @@ -332,66 +349,82 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { val documentReference: DocumentReference, ) - fun getCollection() = firestore.collection("documentReferenceSerialization") - fun getDocument() = getCollection() + val collection = firestore.collection("documentReferenceSerialization") + val document = collection .document("documentReferenceSerialization") - val documentRef1 = getCollection().document("refDoc1").apply { - set(mapOf("value" to 1)) - } - val documentRef2 = getCollection().document("refDoc2").apply { - set(mapOf("value" to 2)) - } - - val data = DataWithDocumentReference(documentRef1) - // store reference - getDocument().set(DataWithDocumentReference.serializer(), data) - // restore data - val savedData = getDocument().get().data(DataWithDocumentReference.serializer()) - assertEquals(data.documentReference.path, savedData.documentReference.path) - - // update data - val updatedData = DataWithDocumentReference(documentRef2) - getDocument().update { - FieldPath(DataWithDocumentReference::documentReference.name).to( - DocumentReferenceSerializer, - updatedData.documentReference, + val documentRef1 = collection.document("refDoc1") + val documentRef2 = collection.document("refDoc2") + + try { + documentRef1.set(mapOf("value" to 1)) + documentRef2.set(mapOf("value" to 2)) + val data = DataWithDocumentReference(documentRef1) + // store reference + document.set(DataWithDocumentReference.serializer(), data) + // restore data + val savedData = document.get().data(DataWithDocumentReference.serializer()) + assertEquals(data.documentReference.path, savedData.documentReference.path) + + // update data + val updatedData = DataWithDocumentReference(documentRef2) + document.update { + FieldPath(DataWithDocumentReference::documentReference.name).to( + DocumentReferenceSerializer, + updatedData.documentReference, + ) + } + // verify update + val updatedSavedData = document.get().data(DataWithDocumentReference.serializer()) + assertEquals( + updatedData.documentReference.path, + updatedSavedData.documentReference.path, ) + } finally { + document.delete() + documentRef1.delete() + documentRef2.delete() } - // verify update - val updatedSavedData = getDocument().get().data(DataWithDocumentReference.serializer()) - assertEquals(updatedData.documentReference.path, updatedSavedData.documentReference.path) } @Test - fun testFieldValuesOps() = runTest { + fun testFieldValuesOps() = testDocument( + firestore.collection("fieldValuesOps") + .document("fieldValuesOps"), + ) { doc -> @Serializable data class TestData(val values: List) - fun getDocument() = firestore.collection("fieldValuesOps") - .document("fieldValuesOps") val data = TestData(listOf(1)) // store - getDocument().set(TestData.serializer(), data) + doc.set(TestData.serializer(), data) // append & verify - getDocument().update(FieldPath(TestData::values.name) to FieldValue.arrayUnion(2)) + doc.update(FieldPath(TestData::values.name) to FieldValue.arrayUnion(2)) - var savedData = getDocument().get().data(TestData.serializer()) + var savedData = doc.get().data(TestData.serializer()) assertEquals(listOf(1, 2), savedData.values) // remove & verify - getDocument().update(FieldPath(TestData::values.name) to FieldValue.arrayRemove(1)) - savedData = getDocument().get().data(TestData.serializer()) + doc.update(FieldPath(TestData::values.name) to FieldValue.arrayRemove(1)) + savedData = doc.get().data(TestData.serializer()) assertEquals(listOf(2), savedData.values) - val list = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) + val list = doc.get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) assertEquals(listOf(2), list) // delete & verify - getDocument().update(FieldPath(TestData::values.name) to FieldValue.delete) - val deletedList = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) + doc.update(FieldPath(TestData::values.name) to FieldValue.delete) + val deletedList = doc.get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) assertNull(deletedList) } private suspend fun nonSkippedDelay(timeout: Duration) = withContext(Dispatchers.Default) { delay(timeout) } + + private fun testDocument(document: DocumentReference, block: suspend CoroutineScope.(DocumentReference) -> Unit) = runTest { + try { + block(document) + } finally { + document.delete() + } + } } diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt index ecc5b386b..f87664321 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/FirestoreSourceTest.kt @@ -21,10 +21,6 @@ class FirestoreSourceTest { ) } - private suspend fun setDoc() { - firestore.collection("testFirestoreQuerying").document("one").set(testDoc) - } - private fun initializeFirebase(persistenceEnabled: Boolean = false) { val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize( context, @@ -58,67 +54,75 @@ class FirestoreSourceTest { } @Test - fun testGetFromServer_withPersistence() = runTest { - initializeFirebase(persistenceEnabled = true) - setDoc() - val doc = firestore.collection("testFirestoreQuerying").document("one").get(Source.SERVER) + fun testGetFromServer_withPersistence() = testFirebaseDoc(true) { + val doc = get(Source.SERVER) assertTrue(doc.exists) assertFalse(doc.metadata.isFromCache) } @Test - fun testGetFromServer_withoutPersistence() = runTest { - initializeFirebase(persistenceEnabled = false) - setDoc() - val doc = firestore.collection("testFirestoreQuerying").document("one").get(Source.SERVER) + fun testGetFromServer_withoutPersistence() = testFirebaseDoc(false) { + val doc = get(Source.SERVER) assertTrue(doc.exists) assertFalse(doc.metadata.isFromCache) } @Test - fun testGetFromCache() = runTest { - initializeFirebase(persistenceEnabled = true) - + fun testGetFromCache() = testFirebaseDoc(true) { // Warm up cache by setting a document - setDoc() + set(testDoc) - val cachedDoc = firestore.collection("testFirestoreQuerying").document("one").get(Source.CACHE) + val cachedDoc = get(Source.CACHE) assertTrue(cachedDoc.exists) assertTrue(cachedDoc.metadata.isFromCache) } @Test - fun testGetFromCache_withoutPersistence() = runTest { - initializeFirebase(persistenceEnabled = false) - setDoc() + fun testGetFromCache_withoutPersistence() = testFirebaseDoc(false) { assertFailsWith(FirebaseFirestoreException::class) { - firestore.collection("testFirestoreQuerying").document("one").get(Source.CACHE) + get(Source.CACHE) } } @Test - fun testGetDefault_withPersistence() = runTest { - initializeFirebase(persistenceEnabled = false) - val doc = firestore.collection("testFirestoreQuerying").document("one").get(Source.DEFAULT) + fun testGetDefault_withPersistence() = testFirebaseDoc(false) { + val doc = get(Source.DEFAULT) assertTrue(doc.exists) assertFalse(doc.metadata.isFromCache) } @Test - fun testGet() = runTest { - initializeFirebase(persistenceEnabled = false) - val doc = firestore.collection("testFirestoreQuerying").document("one").get() + fun testGet() = testFirebaseDoc(false) { + val doc = get() assertTrue(doc.exists) assertFalse(doc.metadata.isFromCache) } @Test - fun testGetDefault_withoutPersistence() = runTest { - initializeFirebase(persistenceEnabled = true) - setDoc() - val doc = firestore.collection("testFirestoreQuerying").document("one").get(Source.DEFAULT) + fun testGetDefault_withoutPersistence() = testFirebaseDoc(true) { + val doc = get(Source.DEFAULT) assertTrue(doc.exists) // Firebase defaults to first fetching from server assertFalse(doc.metadata.isFromCache) } + + private fun testFirebaseDoc( + persistenceEnabled: Boolean, + block: suspend DocumentReference.() -> Unit, + ) = runTest { + initializeFirebase() + val doc = firestore.collection("testFirestoreQuerying").document("one") + doc.set(testDoc) + + Firebase.apps(context).forEach { it.delete() } + + initializeFirebase(persistenceEnabled = persistenceEnabled) + + val newDoc = firestore.collection("testFirestoreQuerying").document("one") + try { + newDoc.block() + } finally { + newDoc.delete() + } + } } diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt index 9d25c5102..665044bda 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/QueryTest.kt @@ -177,12 +177,12 @@ open class QueryTest : BaseFirebaseFirestoreTest() { pathQuery.assertDocuments(FirestoreTest.serializer(), testOne) val serializeFieldQuery = collection.where { - "duration".lessThan(DurationAsLongSerializer(), testThree.duration) + "duration".lessThan(DurationAsIntSerializer(), testThree.duration) } serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) val serializePathQuery = collection.where { - FieldPath(FirestoreTest::duration.name).lessThan(DurationAsLongSerializer(), testTwo.duration) + FieldPath(FirestoreTest::duration.name).lessThan(DurationAsIntSerializer(), testTwo.duration) } serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne) } @@ -200,12 +200,12 @@ open class QueryTest : BaseFirebaseFirestoreTest() { pathQuery.assertDocuments(FirestoreTest.serializer(), testThree) val serializeFieldQuery = collection.where { - "duration".greaterThan(DurationAsLongSerializer(), testOne.duration) + "duration".greaterThan(DurationAsIntSerializer(), testOne.duration) } serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) val serializePathQuery = collection.where { - FieldPath(FirestoreTest::duration.name).greaterThan(DurationAsLongSerializer(), testTwo.duration) + FieldPath(FirestoreTest::duration.name).greaterThan(DurationAsIntSerializer(), testTwo.duration) } serializePathQuery.assertDocuments(FirestoreTest.serializer(), testThree) } @@ -223,12 +223,12 @@ open class QueryTest : BaseFirebaseFirestoreTest() { pathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) val serializeFieldQuery = collection.where { - "duration".lessThanOrEqualTo(DurationAsLongSerializer(), testOne.duration) + "duration".lessThanOrEqualTo(DurationAsIntSerializer(), testOne.duration) } serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testOne) val serializePathQuery = collection.where { - FieldPath(FirestoreTest::duration.name).lessThanOrEqualTo(DurationAsLongSerializer(), testTwo.duration) + FieldPath(FirestoreTest::duration.name).lessThanOrEqualTo(DurationAsIntSerializer(), testTwo.duration) } serializePathQuery.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) } @@ -246,12 +246,12 @@ open class QueryTest : BaseFirebaseFirestoreTest() { pathQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) val serializeFieldQuery = collection.where { - "duration".greaterThanOrEqualTo(DurationAsLongSerializer(), testTwo.duration) + "duration".greaterThanOrEqualTo(DurationAsIntSerializer(), testTwo.duration) } serializeFieldQuery.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) val serializePathQuery = collection.where { - FieldPath(FirestoreTest::duration.name).greaterThanOrEqualTo(DurationAsLongSerializer(), testThree.duration) + FieldPath(FirestoreTest::duration.name).greaterThanOrEqualTo(DurationAsIntSerializer(), testThree.duration) } serializePathQuery.assertDocuments(FirestoreTest.serializer(), testThree) } @@ -397,20 +397,25 @@ open class QueryTest : BaseFirebaseFirestoreTest() { val pastTimestamp = Timestamp(timestamp.seconds - 60, 12345000) // note: iOS truncates 3 last digits of nanoseconds due to internal conversions val futureTimestamp = Timestamp(timestamp.seconds + 60, 78910000) - collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(pastTimestamp)) - collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(futureTimestamp)) + val doc1 = collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(pastTimestamp)) + val doc2 = collection.add(DocumentWithTimestamp.serializer(), DocumentWithTimestamp(futureTimestamp)) - val equalityQueryResult = collection.where { - FieldPath(DocumentWithTimestamp::time.name) equalTo pastTimestamp - }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() + try { + val equalityQueryResult = collection.where { + FieldPath(DocumentWithTimestamp::time.name) equalTo pastTimestamp + }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() - assertEquals(setOf(DocumentWithTimestamp(pastTimestamp)), equalityQueryResult) + assertEquals(setOf(DocumentWithTimestamp(pastTimestamp)), equalityQueryResult) - val gtQueryResult = collection.where { - FieldPath(DocumentWithTimestamp::time.name) greaterThan timestamp - }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() + val gtQueryResult = collection.where { + FieldPath(DocumentWithTimestamp::time.name) greaterThan timestamp + }.get().documents.map { it.data(DocumentWithTimestamp.serializer()) }.toSet() - assertEquals(setOf(DocumentWithTimestamp(futureTimestamp)), gtQueryResult) + assertEquals(setOf(DocumentWithTimestamp(futureTimestamp)), gtQueryResult) + } finally { + doc1.delete() + doc2.delete() + } } @Test diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/TransactionTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/TransactionTest.kt new file mode 100644 index 000000000..5a68d53a8 --- /dev/null +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/TransactionTest.kt @@ -0,0 +1,53 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.runTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.milliseconds + +@IgnoreForAndroidUnitTest +class TransactionTest : BaseFirebaseFirestoreTest() { + + @Test + fun runTransaction() = runTest { + val collection = firestore.collection("testServerTestTransaction") + val document = collection.document("doc1") + try { + document.set( + strategy = FirestoreTest.serializer(), + data = FirestoreTest( + prop1 = "prop1", + count = 0, + ), + ) + val result = firestore.runTransaction { + val count = get(document).data(FirestoreTest.serializer()).count + + if (count < 1) { + update(document) { + FirestoreTest::prop1.name to "newProperty" + FieldPath(FirestoreTest::count.name) to 5 + FirestoreTest::duration.name.to(DurationAsIntSerializer(), 100.milliseconds) + FieldPath(FirestoreTest::nested.name).to( + NestedObject.serializer(), + NestedObject("nested"), + ) + } + true + } else { + throw IllegalStateException("Invalid count") + } + } + assertTrue(result) + + val updated = document.get().data(FirestoreTest.serializer()) + assertEquals("newProperty", updated.prop1) + assertEquals(5, updated.count) + assertEquals(100.milliseconds, updated.duration) + assertEquals(NestedObject("nested"), updated.nested) + } finally { + document.delete() + } + } +} diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt index b06ac071c..f5e8ece3f 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt @@ -12,11 +12,7 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { .collection("testServerTestSetBatch") @Test - fun testSetBatch() = runTest { - val doc1 = collection - .document("test1") - val doc2 = collection - .document("test2") + fun testSetBatch() = testBatch { doc1, doc2 -> val batch = firestore.batch() batch.set( documentRef = doc1, @@ -41,11 +37,7 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { } @Test - fun testSetBatchDoesNotEncodeEmptyValues() = runTest { - val doc1 = collection - .document("test1") - val doc2 = collection - .document("test2") + fun testSetBatchDoesNotEncodeEmptyValues() = testBatch { doc1, doc2 -> val batch = firestore.batch() batch.set( documentRef = doc1, @@ -72,25 +64,19 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { } @Test - fun testUpdateBatch() = runTest { - val doc1 = collection - .document("test1").apply { - set( - FirestoreTest( - prop1 = "prop1", - time = 123.0, - ), - ) - } - val doc2 = collection - .document("test2").apply { - set( - FirestoreTest( - prop1 = "prop2", - time = 456.0, - ), - ) - } + fun testUpdateBatch() = testBatch { doc1, doc2 -> + doc1.set( + FirestoreTest( + prop1 = "prop1", + time = 123.0, + ), + ) + doc2.set( + FirestoreTest( + prop1 = "prop2", + time = 456.0, + ), + ) val batch = firestore.batch() batch.update( @@ -120,25 +106,19 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { } @Test - fun testUpdateBatchDoesNotEncodeEmptyValues() = runTest { - val doc1 = collection - .document("test1").apply { - set( - FirestoreTest( - prop1 = "prop1", - time = 123.0, - ), - ) - } - val doc2 = collection - .document("test2").apply { - set( - FirestoreTest( - prop1 = "prop2", - time = 456.0, - ), - ) - } + fun testUpdateBatchDoesNotEncodeEmptyValues() = testBatch { doc1, doc2 -> + doc1.set( + FirestoreTest( + prop1 = "prop1", + time = 123.0, + ), + ) + doc2.set( + FirestoreTest( + prop1 = "prop2", + time = 456.0, + ), + ) val batch = firestore.batch() batch.update( documentRef = doc1, @@ -169,38 +149,34 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { } @Test - fun testUpdateFieldValuesBatch() = runTest { - val doc1 = collection.document("test1").apply { - set( - FirestoreTest( - prop1 = "prop1", - time = 123.0, - duration = 800.milliseconds, - ), - ) - } + fun testUpdateFieldValuesBatch() = testBatch { doc1, doc2 -> + doc1.set( + FirestoreTest( + prop1 = "prop1", + time = 123.0, + duration = 800.milliseconds, + ), + ) - val doc2 = collection.document("test2").apply { - set( - FirestoreTest( - prop1 = "prop2", - time = 456.0, - duration = 700.milliseconds, - ), - ) - } + doc2.set( + FirestoreTest( + prop1 = "prop2", + time = 456.0, + duration = 700.milliseconds, + ), + ) val batch = firestore.batch() batch.update(doc1) { FirestoreTest::prop1.name to "prop1-updated" FieldPath(FirestoreTest::optional.name) to "notNull" - FirestoreTest::duration.name.to(DurationAsLongSerializer(), 300.milliseconds) + FirestoreTest::duration.name.to(DurationAsIntSerializer(), 300.milliseconds) FieldPath(FirestoreTest::nested.name).to(NestedObject.serializer(), NestedObject("nested")) } batch.update(doc2) { FirestoreTest::prop1.name to "prop2-updated" FieldPath(FirestoreTest::optional.name) to "alsoNotNull" - FirestoreTest::duration.name.to(DurationAsLongSerializer(), 200.milliseconds) + FirestoreTest::duration.name.to(DurationAsIntSerializer(), 200.milliseconds) FieldPath(FirestoreTest::nested.name).to(NestedObject.serializer(), NestedObject("alsoNested")) } batch.commit() @@ -217,4 +193,18 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { assertEquals(200.milliseconds, updatedDoc2.duration) assertEquals(NestedObject("alsoNested"), updatedDoc2.nested) } + + private fun testBatch(block: suspend (DocumentReference, DocumentReference) -> Unit) = runTest { + val doc1 = collection + .document("test1") + val doc2 = collection + .document("test2") + + try { + block(doc1, doc2) + } finally { + doc1.delete() + doc2.delete() + } + } } diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt index d55d5dce9..7f79a7ebc 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -45,7 +45,7 @@ abstract class BaseFirebaseFirestoreTest { val optional: String? = null, val nested: NestedObject? = null, val nestedList: List = emptyList(), - @Serializable(with = DurationAsLongSerializer::class) + @Serializable(with = DurationAsIntSerializer::class) val duration: Duration = Duration.ZERO, ) @@ -54,15 +54,16 @@ abstract class BaseFirebaseFirestoreTest { val prop2: String, ) - class DurationAsLongSerializer : KSerializer { + // Long would be better but JS does not seem to support it on the Firebase level https://stackoverflow.com/questions/31930406/storing-long-type-in-firebase + class DurationAsIntSerializer : KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("millisecondsSinceEpoch", PrimitiveKind.LONG) + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("millisecondsSinceEpoch", PrimitiveKind.INT) override fun serialize(encoder: Encoder, value: Duration) { - encoder.encodeLong(value.inWholeMilliseconds) + encoder.encodeInt(value.inWholeMilliseconds.toInt()) } - override fun deserialize(decoder: Decoder): Duration = decoder.decodeLong().milliseconds + override fun deserialize(decoder: Decoder): Duration = decoder.decodeInt().milliseconds } lateinit var firebaseApp: FirebaseApp diff --git a/firebase-firestore/src/iosTest/kotlin/dev/gitlive/firebase/firestore/ContextSwitchTest.kt b/firebase-firestore/src/iosTest/kotlin/dev/gitlive/firebase/firestore/ContextSwitchTest.kt index e7c6fc04f..494225234 100644 --- a/firebase-firestore/src/iosTest/kotlin/dev/gitlive/firebase/firestore/ContextSwitchTest.kt +++ b/firebase-firestore/src/iosTest/kotlin/dev/gitlive/firebase/firestore/ContextSwitchTest.kt @@ -121,28 +121,38 @@ class ContextSwitchTest { }, ) { data -> - fun getDocument() = firestore.collection("fieldValuesOps") + val doc = firestore.collection("fieldValuesOps") .document("fieldValuesOps") - // store - getDocument().set(strategy = TestData.serializer(), data = TestData(data.initial), merge = false) - - // append & verify - getDocument().update(data.updates[0].op) - - var savedData = getDocument().get().data(TestData.serializer()) - assertEquals(data.updates[0].expected, savedData.values) - - // remove & verify - getDocument().update(data.updates[1].op) - savedData = getDocument().get().data(TestData.serializer()) - assertEquals(data.updates[1].expected, savedData.values) + try { + // store + doc.set( + strategy = TestData.serializer(), + data = TestData(data.initial), + merge = false, + ) - val list = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) - assertEquals(data.updates[1].expected, list) - // delete & verify - getDocument().update(data.updates[2].op) - val deletedList = getDocument().get().get(TestData::values.name, ListSerializer(Int.serializer()).nullable) - assertEquals(data.updates[2].expected, deletedList) + // append & verify + doc.update(data.updates[0].op) + + var savedData = doc.get().data(TestData.serializer()) + assertEquals(data.updates[0].expected, savedData.values) + + // remove & verify + doc.update(data.updates[1].op) + savedData = doc.get().data(TestData.serializer()) + assertEquals(data.updates[1].expected, savedData.values) + + val list = doc.get() + .get(TestData::values.name, ListSerializer(Int.serializer()).nullable) + assertEquals(data.updates[1].expected, list) + // delete & verify + doc.update(data.updates[2].op) + val deletedList = doc.get() + .get(TestData::values.name, ListSerializer(Int.serializer()).nullable) + assertEquals(data.updates[2].expected, deletedList) + } finally { + doc.delete() + } } } From aa1fbb3a87d356742b9441fc480b5575c68fca31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2024 22:08:38 +0000 Subject: [PATCH 32/33] Bump dev.gitlive:firebase-java-sdk from 0.4.5 to 0.4.6 Bumps [dev.gitlive:firebase-java-sdk](https://github.com/GitLiveApp/firebase-java-sdk) from 0.4.5 to 0.4.6. - [Release notes](https://github.com/GitLiveApp/firebase-java-sdk/releases) - [Commits](https://github.com/GitLiveApp/firebase-java-sdk/compare/v0.4.5...v0.4.6) --- updated-dependencies: - dependency-name: dev.gitlive:firebase-java-sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c2a38ad9b..712b20d3a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,7 +5,7 @@ androidx-test-junit = "1.2.1" androidx-test-runner = "1.6.2" ben-manes-versions = "0.51.0" firebase-bom = "33.2.0" -gitlive-firebase-java-sdk = "0.4.5" +gitlive-firebase-java-sdk = "0.4.6" gson = "2.11.0" junit = "4.13.2" kotlin = "2.0.20" From d6e1a94ec0c437f5b5d55637793b3ee6f1dd8445 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 08:41:55 +0000 Subject: [PATCH 33/33] Bump com.android.tools:desugar_jdk_libs from 2.1.0 to 2.1.1 (#616) Bumps [com.android.tools:desugar_jdk_libs](https://github.com/google/desugar_jdk_libs) from 2.1.0 to 2.1.1. - [Changelog](https://github.com/google/desugar_jdk_libs/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/desugar_jdk_libs/commits) --- updated-dependencies: - dependency-name: com.android.tools:desugar_jdk_libs dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrew Reed --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 712b20d3a..7ea0120e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,7 +20,7 @@ firebase-cocoapods = "11.1.0" ios-deploymentTarget = "13.0" test-logger-plugin = "4.0.0" dokka = "1.9.20" -desugar-libs = "2.1.0" +desugar-libs = "2.1.1" [libraries] android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "agp" }