From 625147621434f815aa2bd5c45be3159855970be7 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Thu, 29 Aug 2024 10:39:58 +0200 Subject: [PATCH 01/19] Moves ValueWithSerializer back into public API It had become part of commons-internal which kind of defeats the purpose. Also made FirebaseEncoder/FirebaseDecoder an interface in the public API. Useful for writing custom Serializers that have custom behaviour on Firebase --- .../api/android/firebase-common-internal.api | 76 +------------------ .../api/jvm/firebase-common-internal.api | 76 +------------------ .../gitlive/firebase/internal/_decoders.kt | 6 +- .../gitlive/firebase/internal/_encoders.kt | 4 +- .../gitlive/firebase/internal/Polymorphic.kt | 4 +- .../dev/gitlive/firebase/internal/decoders.kt | 20 ++--- .../dev/gitlive/firebase/internal/encoders.kt | 29 +++---- .../gitlive/firebase/internal/serializers.kt | 4 +- .../gitlive/firebase/internal/_decoders.kt | 8 +- .../gitlive/firebase/internal/_encoders.kt | 6 +- .../gitlive/firebase/internal/_decoders.kt | 8 +- .../gitlive/firebase/internal/_encoders.kt | 6 +- .../api/android/firebase-common.api | 35 +++++++++ firebase-common/api/jvm/firebase-common.api | 35 +++++++++ .../dev/gitlive/firebase/FirebaseDecoder.kt | 5 ++ .../dev/gitlive/firebase/FirebaseEncoder.kt | 5 ++ .../gitlive/firebase/ValueWithSerializer.kt | 11 +++ .../gitlive/firebase/database/ServerValue.kt | 4 +- .../firestore/DocumentReferenceSerializer.kt | 2 +- .../firestore/FieldValueSerializer.kt | 2 +- .../firebase/firestore/GeoPointSerializer.kt | 1 + .../firebase/firestore/TimestampSerializer.kt | 2 + .../gitlive/firebase/firestore/firestore.kt | 2 +- 23 files changed, 149 insertions(+), 202 deletions(-) create mode 100644 firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseDecoder.kt create mode 100644 firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseEncoder.kt create mode 100644 firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/ValueWithSerializer.kt diff --git a/firebase-common-internal/api/android/firebase-common-internal.api b/firebase-common-internal/api/android/firebase-common-internal.api index 44393d3b9..49e83fd95 100644 --- a/firebase-common-internal/api/android/firebase-common-internal.api +++ b/firebase-common-internal/api/android/firebase-common-internal.api @@ -78,59 +78,9 @@ public final class dev/gitlive/firebase/internal/EncodersKt { public static final fun encode (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ljava/lang/Object; public static final fun encodeAsObject (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/internal/EncodedObject; public static synthetic fun encodeAsObject$default (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/internal/EncodedObject; - public static final fun withSerializer (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ljava/lang/Object; -} - -public final class dev/gitlive/firebase/internal/FirebaseClassDecoder : dev/gitlive/firebase/internal/FirebaseCompositeDecoder { - public fun (ILdev/gitlive/firebase/DecodeSettings;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V - public fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)I - public fun decodeSequentially ()Z -} - -public class dev/gitlive/firebase/internal/FirebaseCompositeDecoder : kotlinx/serialization/encoding/CompositeDecoder { - public fun (ILdev/gitlive/firebase/DecodeSettings;Lkotlin/jvm/functions/Function2;)V - public fun decodeBooleanElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z - public fun decodeByteElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)B - public fun decodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)C - public fun decodeCollectionSize (Lkotlinx/serialization/descriptors/SerialDescriptor;)I - public fun decodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)D - public fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)I - public fun decodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)F - public fun decodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Decoder; - public fun decodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)I - public fun decodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)J - public fun decodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object; - public fun decodeSequentially ()Z - public fun decodeSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object; - public fun decodeShortElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)S - public fun decodeStringElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Ljava/lang/String; - public fun endStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)V - public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; -} - -public class dev/gitlive/firebase/internal/FirebaseCompositeEncoder : kotlinx/serialization/encoding/CompositeEncoder { - public fun (Ldev/gitlive/firebase/EncodeSettings;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)V - public synthetic fun (Ldev/gitlive/firebase/EncodeSettings;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun encodeBooleanElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IZ)V - public fun encodeByteElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IB)V - public fun encodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IC)V - public fun encodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ID)V - public fun encodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IF)V - public fun encodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Encoder; - public fun encodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;II)V - public fun encodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IJ)V - public fun encodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V - public final fun encodeObject (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/Object;)V - public final fun encodePolymorphicClassDiscriminator (Ljava/lang/String;Ljava/lang/String;)V - public fun encodeSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V - public fun encodeShortElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IS)V - public fun encodeStringElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V - public fun endStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)V - public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; - public fun shouldEncodeElementDefault (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z } -public final class dev/gitlive/firebase/internal/FirebaseDecoder : kotlinx/serialization/encoding/Decoder { +public final class dev/gitlive/firebase/internal/FirebaseDecoderImpl : dev/gitlive/firebase/FirebaseDecoder { public fun (Ljava/lang/Object;)V public fun (Ljava/lang/Object;Ldev/gitlive/firebase/DecodeSettings;)V public fun beginStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeDecoder; @@ -153,7 +103,7 @@ public final class dev/gitlive/firebase/internal/FirebaseDecoder : kotlinx/seria public final fun getValue ()Ljava/lang/Object; } -public final class dev/gitlive/firebase/internal/FirebaseEncoder : kotlinx/serialization/encoding/Encoder { +public final class dev/gitlive/firebase/internal/FirebaseEncoderImpl : dev/gitlive/firebase/FirebaseEncoder { public fun (Ldev/gitlive/firebase/EncodeSettings;)V public fun (Z)V public fun beginCollection (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/CompositeEncoder; @@ -217,25 +167,3 @@ public final class dev/gitlive/firebase/internal/SpecialValueSerializer : kotlin public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/internal/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/internal/ValueWithSerializer; - public static synthetic fun copy$default (Ldev/gitlive/firebase/internal/ValueWithSerializer;Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;ILjava/lang/Object;)Ldev/gitlive/firebase/internal/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/internal/_decodersKt { - public static final fun getPolymorphicType (Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String; - public static final fun structureDecoder (Ldev/gitlive/firebase/internal/FirebaseDecoder;Lkotlinx/serialization/descriptors/SerialDescriptor;Z)Lkotlinx/serialization/encoding/CompositeDecoder; -} - -public final class dev/gitlive/firebase/internal/_encodersKt { - public static final fun structureEncoder (Ldev/gitlive/firebase/internal/FirebaseEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)Ldev/gitlive/firebase/internal/FirebaseCompositeEncoder; -} - diff --git a/firebase-common-internal/api/jvm/firebase-common-internal.api b/firebase-common-internal/api/jvm/firebase-common-internal.api index 44393d3b9..49e83fd95 100644 --- a/firebase-common-internal/api/jvm/firebase-common-internal.api +++ b/firebase-common-internal/api/jvm/firebase-common-internal.api @@ -78,59 +78,9 @@ public final class dev/gitlive/firebase/internal/EncodersKt { public static final fun encode (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Z)Ljava/lang/Object; public static final fun encodeAsObject (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/internal/EncodedObject; public static synthetic fun encodeAsObject$default (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/gitlive/firebase/internal/EncodedObject; - public static final fun withSerializer (Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;)Ljava/lang/Object; -} - -public final class dev/gitlive/firebase/internal/FirebaseClassDecoder : dev/gitlive/firebase/internal/FirebaseCompositeDecoder { - public fun (ILdev/gitlive/firebase/DecodeSettings;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V - public fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)I - public fun decodeSequentially ()Z -} - -public class dev/gitlive/firebase/internal/FirebaseCompositeDecoder : kotlinx/serialization/encoding/CompositeDecoder { - public fun (ILdev/gitlive/firebase/DecodeSettings;Lkotlin/jvm/functions/Function2;)V - public fun decodeBooleanElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z - public fun decodeByteElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)B - public fun decodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)C - public fun decodeCollectionSize (Lkotlinx/serialization/descriptors/SerialDescriptor;)I - public fun decodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)D - public fun decodeElementIndex (Lkotlinx/serialization/descriptors/SerialDescriptor;)I - public fun decodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)F - public fun decodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Decoder; - public fun decodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)I - public fun decodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)J - public fun decodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object; - public fun decodeSequentially ()Z - public fun decodeSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/DeserializationStrategy;Ljava/lang/Object;)Ljava/lang/Object; - public fun decodeShortElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)S - public fun decodeStringElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Ljava/lang/String; - public fun endStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)V - public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; -} - -public class dev/gitlive/firebase/internal/FirebaseCompositeEncoder : kotlinx/serialization/encoding/CompositeEncoder { - public fun (Ldev/gitlive/firebase/EncodeSettings;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;)V - public synthetic fun (Ldev/gitlive/firebase/EncodeSettings;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun encodeBooleanElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IZ)V - public fun encodeByteElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IB)V - public fun encodeCharElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IC)V - public fun encodeDoubleElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ID)V - public fun encodeFloatElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IF)V - public fun encodeInlineElement (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/Encoder; - public fun encodeIntElement (Lkotlinx/serialization/descriptors/SerialDescriptor;II)V - public fun encodeLongElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IJ)V - public fun encodeNullableSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V - public final fun encodeObject (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/Object;)V - public final fun encodePolymorphicClassDiscriminator (Ljava/lang/String;Ljava/lang/String;)V - public fun encodeSerializableElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V - public fun encodeShortElement (Lkotlinx/serialization/descriptors/SerialDescriptor;IS)V - public fun encodeStringElement (Lkotlinx/serialization/descriptors/SerialDescriptor;ILjava/lang/String;)V - public fun endStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)V - public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; - public fun shouldEncodeElementDefault (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Z } -public final class dev/gitlive/firebase/internal/FirebaseDecoder : kotlinx/serialization/encoding/Decoder { +public final class dev/gitlive/firebase/internal/FirebaseDecoderImpl : dev/gitlive/firebase/FirebaseDecoder { public fun (Ljava/lang/Object;)V public fun (Ljava/lang/Object;Ldev/gitlive/firebase/DecodeSettings;)V public fun beginStructure (Lkotlinx/serialization/descriptors/SerialDescriptor;)Lkotlinx/serialization/encoding/CompositeDecoder; @@ -153,7 +103,7 @@ public final class dev/gitlive/firebase/internal/FirebaseDecoder : kotlinx/seria public final fun getValue ()Ljava/lang/Object; } -public final class dev/gitlive/firebase/internal/FirebaseEncoder : kotlinx/serialization/encoding/Encoder { +public final class dev/gitlive/firebase/internal/FirebaseEncoderImpl : dev/gitlive/firebase/FirebaseEncoder { public fun (Ldev/gitlive/firebase/EncodeSettings;)V public fun (Z)V public fun beginCollection (Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/CompositeEncoder; @@ -217,25 +167,3 @@ public final class dev/gitlive/firebase/internal/SpecialValueSerializer : kotlin public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public final class dev/gitlive/firebase/internal/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/internal/ValueWithSerializer; - public static synthetic fun copy$default (Ldev/gitlive/firebase/internal/ValueWithSerializer;Ljava/lang/Object;Lkotlinx/serialization/SerializationStrategy;ILjava/lang/Object;)Ldev/gitlive/firebase/internal/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/internal/_decodersKt { - public static final fun getPolymorphicType (Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String; - public static final fun structureDecoder (Ldev/gitlive/firebase/internal/FirebaseDecoder;Lkotlinx/serialization/descriptors/SerialDescriptor;Z)Lkotlinx/serialization/encoding/CompositeDecoder; -} - -public final class dev/gitlive/firebase/internal/_encodersKt { - public static final fun structureEncoder (Ldev/gitlive/firebase/internal/FirebaseEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)Ldev/gitlive/firebase/internal/FirebaseCompositeEncoder; -} - diff --git a/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt b/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt index 77644ccfe..4b477364c 100644 --- a/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt +++ b/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt @@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind import kotlinx.serialization.encoding.CompositeDecoder -public actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) { +internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) { StructureKind.CLASS, StructureKind.OBJECT -> decodeAsMap(false) StructureKind.LIST -> (value as? List<*>).orEmpty().let { FirebaseCompositeDecoder(it.size, settings) { _, index -> it[index] } @@ -26,10 +26,10 @@ public actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") } -public actual fun getPolymorphicType(value: Any?, discriminator: String): String = +internal actual fun getPolymorphicType(value: Any?, discriminator: String): String = (value as? Map<*, *>).orEmpty()[discriminator] as String -private fun FirebaseDecoder.decodeAsMap(isNestedPolymorphic: Boolean): CompositeDecoder = (value as? Map<*, *>).orEmpty().let { map -> +private fun FirebaseDecoderImpl.decodeAsMap(isNestedPolymorphic: Boolean): CompositeDecoder = (value as? Map<*, *>).orEmpty().let { map -> FirebaseClassDecoder(map.size, settings, { map.containsKey(it) }) { desc, index -> if (isNestedPolymorphic) { if (desc.getElementName(index) == "value") { diff --git a/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt b/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt index e8d3aca10..eb7be3ba2 100644 --- a/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt +++ b/firebase-common-internal/src/androidMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt @@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind import kotlin.collections.set -public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { +internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { StructureKind.LIST -> mutableListOf() .also { value = it } .let { FirebaseCompositeEncoder(settings) { _, index, value -> it.add(index, value) } } @@ -20,7 +20,7 @@ public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor) else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") } -private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = mutableMapOf() +private fun FirebaseEncoderImpl.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = mutableMapOf() .also { value = it } .let { FirebaseCompositeEncoder( diff --git a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/Polymorphic.kt b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/Polymorphic.kt index 77bb77dc7..2297be79b 100644 --- a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/Polymorphic.kt +++ b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/Polymorphic.kt @@ -12,7 +12,7 @@ import kotlinx.serialization.internal.AbstractPolymorphicSerializer * See https://github.com/Kotlin/kotlinx.serialization/blob/master/formats/json/commonMain/src/kotlinx/serialization/json/internal/Polymorphic.kt */ @Suppress("UNCHECKED_CAST") -internal fun FirebaseEncoder.encodePolymorphically( +internal fun FirebaseEncoderImpl.encodePolymorphically( serializer: SerializationStrategy, value: T, ifPolymorphic: (String) -> Unit, @@ -34,7 +34,7 @@ internal fun FirebaseEncoder.encodePolymorphically( } @Suppress("UNCHECKED_CAST") -internal fun FirebaseDecoder.decodeSerializableValuePolymorphic( +internal fun FirebaseDecoderImpl.decodeSerializableValuePolymorphic( value: Any?, deserializer: DeserializationStrategy, ): T { diff --git a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/decoders.kt b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/decoders.kt index 084bc4f62..27952ac7d 100644 --- a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/decoders.kt +++ b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/decoders.kt @@ -5,6 +5,7 @@ package dev.gitlive.firebase.internal import dev.gitlive.firebase.DecodeSettings +import dev.gitlive.firebase.FirebaseDecoder import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerializationException @@ -31,12 +32,13 @@ public inline fun decode(strategy: DeserializationStrategy, value: Any?, @PublishedApi internal fun decode(strategy: DeserializationStrategy, value: Any?, decodeSettings: DecodeSettings): T { require(value != null || strategy.descriptor.isNullable) { "Value was null for non-nullable type ${strategy.descriptor.serialName}" } - return FirebaseDecoder(value, decodeSettings).decodeSerializableValue(strategy) + return FirebaseDecoderImpl(value, decodeSettings).decodeSerializableValue(strategy) } -public expect fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder -public expect fun getPolymorphicType(value: Any?, discriminator: String): String +internal expect fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder +internal expect fun getPolymorphicType(value: Any?, discriminator: String): String -public class FirebaseDecoder(public val value: Any?, internal val settings: DecodeSettings) : Decoder { +@PublishedApi +internal class FirebaseDecoderImpl(val value: Any?, internal val settings: DecodeSettings) : FirebaseDecoder { public constructor(value: Any?) : this(value, DecodeSettingsImpl()) @@ -68,12 +70,12 @@ public class FirebaseDecoder(public val value: Any?, internal val settings: Deco override fun decodeNull(): Nothing? = decodeNull(value) - override fun decodeInline(descriptor: SerialDescriptor): Decoder = FirebaseDecoder(value, settings) + override fun decodeInline(descriptor: SerialDescriptor): Decoder = FirebaseDecoderImpl(value, settings) override fun decodeSerializableValue(deserializer: DeserializationStrategy): T = decodeSerializableValuePolymorphic(value, deserializer) } -public class FirebaseClassDecoder( +internal class FirebaseClassDecoder( size: Int, settings: DecodeSettings, private val containsKey: (name: String) -> Boolean, @@ -91,7 +93,7 @@ public class FirebaseClassDecoder( ?: DECODE_DONE } -public open class FirebaseCompositeDecoder( +internal open class FirebaseCompositeDecoder( private val size: Int, internal val settings: DecodeSettings, private val get: (descriptor: SerialDescriptor, index: Int) -> Any?, @@ -111,7 +113,7 @@ public open class FirebaseCompositeDecoder( deserializer: DeserializationStrategy, previousValue: T?, ): T = decodeElement(descriptor, index) { - deserializer.deserialize(FirebaseDecoder(it, settings)) + deserializer.deserialize(FirebaseDecoderImpl(it, settings)) } override fun decodeBooleanElement(descriptor: SerialDescriptor, index: Int): Boolean = @@ -160,7 +162,7 @@ public open class FirebaseCompositeDecoder( @ExperimentalSerializationApi override fun decodeInlineElement(descriptor: SerialDescriptor, index: Int): Decoder = decodeElement(descriptor, index) { - FirebaseDecoder(it, settings) + FirebaseDecoderImpl(it, settings) } private fun decodeElement(descriptor: SerialDescriptor, index: Int, decoder: (Any?) -> T): T = try { diff --git a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/encoders.kt b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/encoders.kt index c6c9e4abf..474aeea57 100644 --- a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/encoders.kt +++ b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/encoders.kt @@ -5,6 +5,8 @@ package dev.gitlive.firebase.internal import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.FirebaseEncoder +import dev.gitlive.firebase.ValueWithSerializer import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.descriptors.SerialDescriptor @@ -22,7 +24,7 @@ public inline fun encode(strategy: SerializationStrategy, value: T, build @PublishedApi internal fun encode(strategy: SerializationStrategy, value: T, encodeSettings: EncodeSettings): Any? = - FirebaseEncoder(encodeSettings).apply { encodeSerializableValue(strategy, value) }.value + FirebaseEncoderImpl(encodeSettings).apply { encodeSerializableValue(strategy, value) }.value @Deprecated("Deprecated. Use builder instead", replaceWith = ReplaceWith("encode(value) { this.encodeDefaults = shouldEncodeElementDefault }")) public inline fun encode(value: T, shouldEncodeElementDefault: Boolean): Any? = encode(value) { @@ -60,7 +62,7 @@ public inline fun encodeAsObject(value: T, buildSettings: Enco @PublishedApi internal inline fun encode(value: T, encodeSettings: EncodeSettings): Any? = value?.let { - FirebaseEncoder(encodeSettings).apply { + FirebaseEncoderImpl(encodeSettings).apply { if (it is ValueWithSerializer<*> && it.value is T) { @Suppress("UNCHECKED_CAST") (it as ValueWithSerializer).let { @@ -72,19 +74,12 @@ internal inline fun encode(value: T, encodeSettings: EncodeSettings) }.value } -/** - * An extension which which serializer to use for value. Handy in updating fields by name or path - * where using annotation is not possible - * @return a value with a custom serializer. - */ -public fun T.withSerializer(serializer: SerializationStrategy): Any = ValueWithSerializer(this, serializer) -public data class ValueWithSerializer(val value: T, val serializer: SerializationStrategy) +internal expect fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder -public expect fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder - -public class FirebaseEncoder( +@PublishedApi +internal class FirebaseEncoderImpl( internal val settings: EncodeSettings, -) : Encoder { +) : FirebaseEncoder { public constructor(shouldEncodeElementDefault: Boolean) : this( EncodeSettingsImpl.Builder().apply { this.encodeDefaults = shouldEncodeElementDefault }.buildEncodeSettings(), @@ -162,7 +157,7 @@ public class FirebaseEncoder( } } -public open class FirebaseCompositeEncoder( +internal open class FirebaseCompositeEncoder( private val settings: EncodeSettings, private val end: () -> Unit = {}, private val setPolymorphicType: (String, String) -> Unit = { _, _ -> }, @@ -190,7 +185,7 @@ public open class FirebaseCompositeEncoder( descriptor, index, value?.let { - FirebaseEncoder(settings).apply { + FirebaseEncoderImpl(settings).apply { encodeSerializableValue(serializer, value) }.value }, @@ -204,7 +199,7 @@ public open class FirebaseCompositeEncoder( ): Unit = set( descriptor, index, - FirebaseEncoder(settings).apply { + FirebaseEncoderImpl(settings).apply { encodeSerializableValue(serializer, value) }.value, ) @@ -231,7 +226,7 @@ public open class FirebaseCompositeEncoder( @ExperimentalSerializationApi override fun encodeInlineElement(descriptor: SerialDescriptor, index: Int): Encoder = - FirebaseEncoder(settings) + FirebaseEncoderImpl(settings) public fun encodePolymorphicClassDiscriminator(discriminator: String, type: String) { setPolymorphicType(discriminator, type) diff --git a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/serializers.kt b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/serializers.kt index 41f319f88..cb1b1fb00 100644 --- a/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/serializers.kt +++ b/firebase-common-internal/src/commonMain/kotlin/dev/gitlive/firebase/internal/serializers.kt @@ -128,14 +128,14 @@ public class SpecialValueSerializer( override val descriptor: SerialDescriptor = buildClassSerialDescriptor(serialName) { } override fun serialize(encoder: Encoder, value: T) { - if (encoder is FirebaseEncoder) { + if (encoder is FirebaseEncoderImpl) { encoder.value = toNativeValue(value) } else { throw SerializationException("This serializer must be used with FirebaseEncoder") } } - override fun deserialize(decoder: Decoder): T = if (decoder is FirebaseDecoder) { + override fun deserialize(decoder: Decoder): T = if (decoder is FirebaseDecoderImpl) { fromNativeValue(decoder.value) } else { throw SerializationException("This serializer must be used with FirebaseDecoder") diff --git a/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt b/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt index 00400b622..561d4c762 100644 --- a/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt +++ b/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt @@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.PolymorphicKind import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind -public actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) { +internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) { StructureKind.CLASS, StructureKind.OBJECT -> decodeAsMap(false) StructureKind.LIST -> decodeAsList() StructureKind.MAP -> (value as? Map<*, *>).orEmpty().entries.toList().let { @@ -19,13 +19,13 @@ public actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") } -public actual fun getPolymorphicType(value: Any?, discriminator: String): String = +internal actual fun getPolymorphicType(value: Any?, discriminator: String): String = (value as? Map<*, *>).orEmpty()[discriminator] as String -private fun FirebaseDecoder.decodeAsList(): CompositeDecoder = (value as? List<*>).orEmpty().let { +private fun FirebaseDecoderImpl.decodeAsList(): CompositeDecoder = (value as? List<*>).orEmpty().let { FirebaseCompositeDecoder(it.size, settings) { _, index -> it[index] } } -private fun FirebaseDecoder.decodeAsMap(isNestedPolymorphic: Boolean): CompositeDecoder = (value as? Map<*, *>).orEmpty().let { map -> +private fun FirebaseDecoderImpl.decodeAsMap(isNestedPolymorphic: Boolean): CompositeDecoder = (value as? Map<*, *>).orEmpty().let { map -> FirebaseClassDecoder(map.size, settings, { map.containsKey(it) }) { desc, index -> if (isNestedPolymorphic) { if (desc.getElementName(index) == "value") { diff --git a/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt b/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt index efd200c20..bab44db4e 100644 --- a/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt +++ b/firebase-common-internal/src/iosMain/kotlin/dev/gitlive/firebase/internal/_encoders.kt @@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind import kotlin.collections.set -public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { +internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { StructureKind.LIST -> encodeAsList() StructureKind.MAP -> mutableListOf() .let { FirebaseCompositeEncoder(settings, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } } @@ -18,10 +18,10 @@ public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor) else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") } -private fun FirebaseEncoder.encodeAsList(): FirebaseCompositeEncoder = mutableListOf() +private fun FirebaseEncoderImpl.encodeAsList(): FirebaseCompositeEncoder = mutableListOf() .also { value = it } .let { FirebaseCompositeEncoder(settings) { _, index, value -> it.add(index, value) } } -private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = mutableMapOf() +private fun FirebaseEncoderImpl.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = mutableMapOf() .also { value = it } .let { FirebaseCompositeEncoder( diff --git a/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt b/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt index 05701df40..1787c1cc4 100644 --- a/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt +++ b/firebase-common-internal/src/jsMain/kotlin/dev/gitlive/firebase/internal/_decoders.kt @@ -11,7 +11,7 @@ import kotlinx.serialization.descriptors.StructureKind import kotlinx.serialization.encoding.CompositeDecoder import kotlin.js.Json -public actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) { +internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) { StructureKind.CLASS, StructureKind.OBJECT -> decodeAsMap(false) StructureKind.LIST -> decodeAsList() StructureKind.MAP -> (js("Object").entries(value) as Array>).let { @@ -39,15 +39,15 @@ public actual fun FirebaseDecoder.structureDecoder(descriptor: SerialDescriptor, } @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") -public actual fun getPolymorphicType(value: Any?, discriminator: String): String = +internal actual fun getPolymorphicType(value: Any?, discriminator: String): String = (value as Json)[discriminator] as String -private fun FirebaseDecoder.decodeAsList(): CompositeDecoder = (value as Array<*>).let { +private fun FirebaseDecoderImpl.decodeAsList(): CompositeDecoder = (value as Array<*>).let { FirebaseCompositeDecoder(it.size, settings) { _, index -> it[index] } } @Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE") -private fun FirebaseDecoder.decodeAsMap(isNestedPolymorphic: Boolean): CompositeDecoder = (value as Json).let { json -> +private fun FirebaseDecoderImpl.decodeAsMap(isNestedPolymorphic: Boolean): CompositeDecoder = (value as Json).let { json -> FirebaseClassDecoder(js("Object").keys(value).length as Int, settings, { json[it] != undefined }) { desc, index -> if (isNestedPolymorphic) { if (desc.getElementName(index) == "value") { 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 1e21549a0..7121128d0 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 @@ -9,7 +9,7 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind import kotlin.js.json -public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { +internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) { StructureKind.LIST -> encodeAsList(descriptor) StructureKind.MAP -> { val map = json() @@ -28,10 +28,10 @@ public actual fun FirebaseEncoder.structureEncoder(descriptor: SerialDescriptor) else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet") } -private fun FirebaseEncoder.encodeAsList(descriptor: SerialDescriptor): FirebaseCompositeEncoder = Array(descriptor.elementsCount) { null } +private fun FirebaseEncoderImpl.encodeAsList(descriptor: SerialDescriptor): FirebaseCompositeEncoder = Array(descriptor.elementsCount) { null } .also { value = it } .let { FirebaseCompositeEncoder(settings) { _, index, value -> it[index] = value } } -private fun FirebaseEncoder.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = json() +private fun FirebaseEncoderImpl.encodeAsMap(descriptor: SerialDescriptor): FirebaseCompositeEncoder = json() .also { value = it } .let { FirebaseCompositeEncoder( diff --git a/firebase-common/api/android/firebase-common.api b/firebase-common/api/android/firebase-common.api index 2b70a6e8a..9724b86d4 100644 --- a/firebase-common/api/android/firebase-common.api +++ b/firebase-common/api/android/firebase-common.api @@ -33,3 +33,38 @@ public synthetic class dev/gitlive/firebase/FirebaseClassDiscriminator$Impl : de public final synthetic fun discriminator ()Ljava/lang/String; } +public abstract interface class dev/gitlive/firebase/FirebaseDecoder : kotlinx/serialization/encoding/Decoder { +} + +public final class dev/gitlive/firebase/FirebaseDecoder$DefaultImpls { + public static fun decodeNullableSerializableValue (Ldev/gitlive/firebase/FirebaseDecoder;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; + public static fun decodeSerializableValue (Ldev/gitlive/firebase/FirebaseDecoder;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; +} + +public abstract interface class dev/gitlive/firebase/FirebaseEncoder : kotlinx/serialization/encoding/Encoder { +} + +public final class dev/gitlive/firebase/FirebaseEncoder$DefaultImpls { + public static fun beginCollection (Ldev/gitlive/firebase/FirebaseEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/CompositeEncoder; + public static fun encodeNotNullMark (Ldev/gitlive/firebase/FirebaseEncoder;)V + public static fun encodeNullableSerializableValue (Ldev/gitlive/firebase/FirebaseEncoder;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + 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 2b70a6e8a..9724b86d4 100644 --- a/firebase-common/api/jvm/firebase-common.api +++ b/firebase-common/api/jvm/firebase-common.api @@ -33,3 +33,38 @@ public synthetic class dev/gitlive/firebase/FirebaseClassDiscriminator$Impl : de public final synthetic fun discriminator ()Ljava/lang/String; } +public abstract interface class dev/gitlive/firebase/FirebaseDecoder : kotlinx/serialization/encoding/Decoder { +} + +public final class dev/gitlive/firebase/FirebaseDecoder$DefaultImpls { + public static fun decodeNullableSerializableValue (Ldev/gitlive/firebase/FirebaseDecoder;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; + public static fun decodeSerializableValue (Ldev/gitlive/firebase/FirebaseDecoder;Lkotlinx/serialization/DeserializationStrategy;)Ljava/lang/Object; +} + +public abstract interface class dev/gitlive/firebase/FirebaseEncoder : kotlinx/serialization/encoding/Encoder { +} + +public final class dev/gitlive/firebase/FirebaseEncoder$DefaultImpls { + public static fun beginCollection (Ldev/gitlive/firebase/FirebaseEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;I)Lkotlinx/serialization/encoding/CompositeEncoder; + public static fun encodeNotNullMark (Ldev/gitlive/firebase/FirebaseEncoder;)V + public static fun encodeNullableSerializableValue (Ldev/gitlive/firebase/FirebaseEncoder;Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V + 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/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseDecoder.kt b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseDecoder.kt new file mode 100644 index 000000000..2dbf07b44 --- /dev/null +++ b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseDecoder.kt @@ -0,0 +1,5 @@ +package dev.gitlive.firebase + +import kotlinx.serialization.encoding.Decoder + +public interface FirebaseDecoder : Decoder diff --git a/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseEncoder.kt b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseEncoder.kt new file mode 100644 index 000000000..f33f69fbb --- /dev/null +++ b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/FirebaseEncoder.kt @@ -0,0 +1,5 @@ +package dev.gitlive.firebase + +import kotlinx.serialization.encoding.Encoder + +public interface FirebaseEncoder : Encoder diff --git a/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/ValueWithSerializer.kt b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/ValueWithSerializer.kt new file mode 100644 index 000000000..84ed4713b --- /dev/null +++ b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/ValueWithSerializer.kt @@ -0,0 +1,11 @@ +package dev.gitlive.firebase + +import kotlinx.serialization.SerializationStrategy + +/** + * An extension which which serializer to use for value. Handy in updating fields by name or path + * where using annotation is not possible + * @return a value with a custom serializer. + */ +public fun T.withSerializer(serializer: SerializationStrategy): Any = ValueWithSerializer(this, serializer) +public data class ValueWithSerializer(val value: T, val serializer: SerializationStrategy) diff --git a/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt b/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt index db1f7f344..e393d118b 100644 --- a/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt +++ b/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/ServerValue.kt @@ -1,7 +1,7 @@ package dev.gitlive.firebase.database -import dev.gitlive.firebase.internal.FirebaseDecoder -import dev.gitlive.firebase.internal.FirebaseEncoder +import dev.gitlive.firebase.FirebaseEncoder +import dev.gitlive.firebase.FirebaseDecoder import dev.gitlive.firebase.internal.SpecialValueSerializer import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceSerializer.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceSerializer.kt index 945230bc7..10fa9341f 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceSerializer.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/DocumentReferenceSerializer.kt @@ -1,7 +1,7 @@ package dev.gitlive.firebase.firestore +import dev.gitlive.firebase.FirebaseEncoder import dev.gitlive.firebase.firestore.internal.NativeDocumentReference -import dev.gitlive.firebase.internal.FirebaseEncoder import dev.gitlive.firebase.internal.SpecialValueSerializer import kotlinx.serialization.KSerializer import kotlinx.serialization.SerializationException diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueSerializer.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueSerializer.kt index 561dcb201..d2717474d 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueSerializer.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueSerializer.kt @@ -1,6 +1,6 @@ package dev.gitlive.firebase.firestore -import dev.gitlive.firebase.internal.FirebaseEncoder +import dev.gitlive.firebase.FirebaseEncoder import dev.gitlive.firebase.internal.SpecialValueSerializer import kotlinx.serialization.KSerializer import kotlinx.serialization.SerializationException diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/GeoPointSerializer.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/GeoPointSerializer.kt index cb46e1792..7228704bc 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/GeoPointSerializer.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/GeoPointSerializer.kt @@ -1,5 +1,6 @@ package dev.gitlive.firebase.firestore +import dev.gitlive.firebase.FirebaseEncoder import dev.gitlive.firebase.internal.SpecialValueSerializer import kotlinx.serialization.KSerializer import kotlinx.serialization.SerializationException diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/TimestampSerializer.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/TimestampSerializer.kt index f970b0801..791e4d6f5 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/TimestampSerializer.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/TimestampSerializer.kt @@ -1,5 +1,7 @@ package dev.gitlive.firebase.firestore +import dev.gitlive.firebase.FirebaseEncoder +import dev.gitlive.firebase.FirebaseDecoder import dev.gitlive.firebase.internal.SpecialValueSerializer import dev.gitlive.firebase.firestore.DoubleAsTimestampSerializer.SERVER_TIMESTAMP import kotlinx.serialization.KSerializer 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..50b90c44c 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,7 @@ 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.internal.withSerializer +import dev.gitlive.firebase.withSerializer import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.delay From 1c28ed3bbe15d85f7b329862626575833b9c4f71 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Fri, 30 Aug 2024 10:54:13 +0200 Subject: [PATCH 02/19] 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 03/19] 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 04/19] 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 05/19] 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 c612f9c9e52874e5066d12925f22d41da7efccff Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 2 Sep 2024 17:37:10 +0200 Subject: [PATCH 06/19] 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 90f870c68501dd99bfe4e1d36d33947dc7a48c20 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 2 Sep 2024 21:50:11 +0200 Subject: [PATCH 07/19] 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 4176fe6d63736b01adcac926910f5890b8f517c3 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Fri, 13 Sep 2024 13:23:03 +0200 Subject: [PATCH 08/19] Make builders abstract to allow for testing --- .../api/android/firebase-firestore.api | 11 +++++----- .../api/jvm/firebase-firestore.api | 11 +++++----- .../firebase/firestore/FieldValueBuilder.kt | 7 ++----- .../firestore/FieldsAndValuesBuilder.kt | 12 +++-------- .../gitlive/firebase/firestore/firestore.kt | 14 ++++++------- .../firestore/internal/FieldValueBuilder.kt | 15 +++++++++++++ .../internal/FieldsAndValuesBuilder.kt | 21 +++++++++++++++++++ 7 files changed, 60 insertions(+), 31 deletions(-) create mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt create mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index 9cf847e6b..21a2909de 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -160,8 +160,8 @@ 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 abstract class dev/gitlive/firebase/firestore/FieldValueBuilder { + public abstract 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 @@ -176,13 +176,14 @@ 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 abstract class dev/gitlive/firebase/firestore/FieldsAndValuesBuilder { + public fun ()V 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 fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)V + public abstract fun toEncoded (Ljava/lang/String;Ljava/lang/Object;)V } public abstract class dev/gitlive/firebase/firestore/Filter { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 6b5abda69..5c628e0aa 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -160,8 +160,8 @@ 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 abstract class dev/gitlive/firebase/firestore/FieldValueBuilder { + public abstract 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 @@ -176,13 +176,14 @@ 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 abstract class dev/gitlive/firebase/firestore/FieldsAndValuesBuilder { + public fun ()V 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 fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)V + public abstract fun toEncoded (Ljava/lang/String;Ljava/lang/Object;)V } public abstract class dev/gitlive/firebase/firestore/Filter { 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 index 53d5a0d13..626ab89f2 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt @@ -3,9 +3,8 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.EncodeSettings import kotlinx.serialization.SerializationStrategy -public class FieldValueBuilder internal constructor() { +public abstract class FieldValueBuilder internal constructor() { - internal val fieldValues: MutableList = mutableListOf() public var buildSettings: EncodeSettings.Builder.() -> Unit = { encodeDefaults = true } @@ -19,7 +18,5 @@ public class FieldValueBuilder internal constructor() { } @PublishedApi - internal fun addEncoded(encodedValue: Any) { - fieldValues += encodedValue - } + internal abstract fun addEncoded(encodedValue: Any) } 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 index aba64b228..b3886f4f8 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt @@ -1,12 +1,10 @@ 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() { +public abstract class FieldsAndValuesBuilder { - internal val fieldAndValues: MutableList = mutableListOf() public var buildSettings: EncodeSettings.Builder.() -> Unit = { encodeDefaults = true } @@ -28,12 +26,8 @@ public class FieldsAndValuesBuilder internal constructor() { } @PublishedApi - internal fun String.toEncoded(encodedValue: Any?) { - fieldAndValues += FieldAndValue.WithStringField(this, encodedValue) - } + internal abstract fun String.toEncoded(encodedValue: Any?) @PublishedApi - internal fun FieldPath.toEncoded(encodedValue: Any?) { - fieldAndValues += FieldAndValue.WithFieldPath(this, encodedValue) - } + internal abstract fun FieldPath.toEncoded(encodedValue: Any?) } 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 c87f4194c..2a5f9ad73 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 @@ -224,7 +224,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N public fun update( documentRef: DocumentReference, fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, - ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) + ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, dev.gitlive.firebase.firestore.internal.FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, encodedData)) @@ -263,7 +263,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun startAfter(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAfter(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + public fun startAfter(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAfter(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun startAt(document: DocumentSnapshot): Query = Query(nativeQuery.startAt(document.native)) public fun startAt(vararg fieldValues: Any?): Query = startAt({}, *fieldValues) @@ -275,7 +275,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun startAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + public fun startAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAt(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun endBefore(document: DocumentSnapshot): Query = Query(nativeQuery.endBefore(document.native)) public fun endBefore(vararg fieldValues: Any?): Query = endBefore({}, *fieldValues) @@ -287,7 +287,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun endBefore(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endBefore(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + public fun endBefore(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endBefore(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) public fun endAt(document: DocumentSnapshot): Query = Query(nativeQuery.endAt(document.native)) public fun endAt(vararg fieldValues: Any?): Query = endAt({}, *fieldValues) @@ -299,7 +299,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun endAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + public fun endAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endAt(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) } @Deprecated("Deprecated in favor of using a [FilterBuilder]", replaceWith = ReplaceWith("where { field equalTo equalTo }", "dev.gitlive.firebase.firestore")) @@ -461,7 +461,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na ): WriteBatch = WriteBatch( nativeWrapper.updateEncoded( documentRef, - FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, + dev.gitlive.firebase.firestore.internal.FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, ), ) @@ -633,7 +633,7 @@ public data class DocumentReference internal constructor(internal val native: Na public suspend fun update( fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ) { - native.updateEncoded(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) + native.updateEncoded(dev.gitlive.firebase.firestore.internal.FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) } public suspend fun delete() { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt new file mode 100644 index 000000000..16121a389 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt @@ -0,0 +1,15 @@ +package dev.gitlive.firebase.firestore.internal + +import kotlin.experimental.ExperimentalObjCName +import kotlin.native.ObjCName + +@OptIn(ExperimentalObjCName::class) +@ObjCName("FieldValueBuilderImpl") +internal class FieldValueBuilder : dev.gitlive.firebase.firestore.FieldValueBuilder() { + + internal val fieldValues: MutableList = mutableListOf() + + override fun addEncoded(encodedValue: Any) { + fieldValues += encodedValue + } +} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt new file mode 100644 index 000000000..08307d13f --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt @@ -0,0 +1,21 @@ +package dev.gitlive.firebase.firestore.internal + +import dev.gitlive.firebase.firestore.FieldPath +import dev.gitlive.firebase.firestore.FieldsAndValuesBuilder +import kotlin.experimental.ExperimentalObjCName +import kotlin.native.ObjCName + +@OptIn(ExperimentalObjCName::class) +@ObjCName("FieldsAndValuesBuilderImpl") +internal class FieldsAndValuesBuilder : FieldsAndValuesBuilder() { + + internal val fieldAndValues: MutableList = mutableListOf() + + override fun String.toEncoded(encodedValue: Any?) { + fieldAndValues += FieldAndValue.WithStringField(this, encodedValue) + } + + override fun FieldPath.toEncoded(encodedValue: Any?) { + fieldAndValues += FieldAndValue.WithFieldPath(this, encodedValue) + } +} From a138c10179b10795348b15e46ae49b863ed6e97c Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Fri, 13 Sep 2024 15:04:10 +0200 Subject: [PATCH 09/19] Revert "Make builders abstract to allow for testing" This reverts commit 4176fe6d63736b01adcac926910f5890b8f517c3. --- .../api/android/firebase-firestore.api | 11 +++++----- .../api/jvm/firebase-firestore.api | 11 +++++----- .../firebase/firestore/FieldValueBuilder.kt | 7 +++++-- .../firestore/FieldsAndValuesBuilder.kt | 12 ++++++++--- .../gitlive/firebase/firestore/firestore.kt | 14 ++++++------- .../firestore/internal/FieldValueBuilder.kt | 15 ------------- .../internal/FieldsAndValuesBuilder.kt | 21 ------------------- 7 files changed, 31 insertions(+), 60 deletions(-) delete mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt delete mode 100644 firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index 21a2909de..9cf847e6b 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -160,8 +160,8 @@ public final class dev/gitlive/firebase/firestore/FieldValue$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public abstract class dev/gitlive/firebase/firestore/FieldValueBuilder { - public abstract fun addEncoded (Ljava/lang/Object;)V +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 @@ -176,14 +176,13 @@ public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public abstract class dev/gitlive/firebase/firestore/FieldsAndValuesBuilder { - public fun ()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 abstract fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)V - public abstract fun toEncoded (Ljava/lang/String;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 { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 5c628e0aa..6b5abda69 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -160,8 +160,8 @@ public final class dev/gitlive/firebase/firestore/FieldValue$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public abstract class dev/gitlive/firebase/firestore/FieldValueBuilder { - public abstract fun addEncoded (Ljava/lang/Object;)V +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 @@ -176,14 +176,13 @@ public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } -public abstract class dev/gitlive/firebase/firestore/FieldsAndValuesBuilder { - public fun ()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 abstract fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)V - public abstract fun toEncoded (Ljava/lang/String;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 { 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 index 626ab89f2..53d5a0d13 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt @@ -3,8 +3,9 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.EncodeSettings import kotlinx.serialization.SerializationStrategy -public abstract class FieldValueBuilder internal constructor() { +public class FieldValueBuilder internal constructor() { + internal val fieldValues: MutableList = mutableListOf() public var buildSettings: EncodeSettings.Builder.() -> Unit = { encodeDefaults = true } @@ -18,5 +19,7 @@ public abstract class FieldValueBuilder internal constructor() { } @PublishedApi - internal abstract fun addEncoded(encodedValue: Any) + 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 index b3886f4f8..aba64b228 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt @@ -1,10 +1,12 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.firestore.internal.FieldAndValue import kotlinx.serialization.SerializationStrategy -public abstract class FieldsAndValuesBuilder { +public class FieldsAndValuesBuilder internal constructor() { + internal val fieldAndValues: MutableList = mutableListOf() public var buildSettings: EncodeSettings.Builder.() -> Unit = { encodeDefaults = true } @@ -26,8 +28,12 @@ public abstract class FieldsAndValuesBuilder { } @PublishedApi - internal abstract fun String.toEncoded(encodedValue: Any?) + internal fun String.toEncoded(encodedValue: Any?) { + fieldAndValues += FieldAndValue.WithStringField(this, encodedValue) + } @PublishedApi - internal abstract fun FieldPath.toEncoded(encodedValue: Any?) + 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 2a5f9ad73..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 @@ -224,7 +224,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N public fun update( documentRef: DocumentReference, fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, - ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, dev.gitlive.firebase.firestore.internal.FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) + ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, encodedData)) @@ -263,7 +263,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun startAfter(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAfter(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + 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?): Query = startAt({}, *fieldValues) @@ -275,7 +275,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun startAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAt(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + 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?): Query = endBefore({}, *fieldValues) @@ -287,7 +287,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun endBefore(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endBefore(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + 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?): Query = endAt({}, *fieldValues) @@ -299,7 +299,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue } } - public fun endAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endAt(*dev.gitlive.firebase.firestore.internal.FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + 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")) @@ -461,7 +461,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na ): WriteBatch = WriteBatch( nativeWrapper.updateEncoded( documentRef, - dev.gitlive.firebase.firestore.internal.FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, + FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, ), ) @@ -633,7 +633,7 @@ public data class DocumentReference internal constructor(internal val native: Na public suspend fun update( fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, ) { - native.updateEncoded(dev.gitlive.firebase.firestore.internal.FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) + native.updateEncoded(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) } public suspend fun delete() { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt deleted file mode 100644 index 16121a389..000000000 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldValueBuilder.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.gitlive.firebase.firestore.internal - -import kotlin.experimental.ExperimentalObjCName -import kotlin.native.ObjCName - -@OptIn(ExperimentalObjCName::class) -@ObjCName("FieldValueBuilderImpl") -internal class FieldValueBuilder : dev.gitlive.firebase.firestore.FieldValueBuilder() { - - internal val fieldValues: MutableList = mutableListOf() - - override fun addEncoded(encodedValue: Any) { - fieldValues += encodedValue - } -} diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt deleted file mode 100644 index 08307d13f..000000000 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/internal/FieldsAndValuesBuilder.kt +++ /dev/null @@ -1,21 +0,0 @@ -package dev.gitlive.firebase.firestore.internal - -import dev.gitlive.firebase.firestore.FieldPath -import dev.gitlive.firebase.firestore.FieldsAndValuesBuilder -import kotlin.experimental.ExperimentalObjCName -import kotlin.native.ObjCName - -@OptIn(ExperimentalObjCName::class) -@ObjCName("FieldsAndValuesBuilderImpl") -internal class FieldsAndValuesBuilder : FieldsAndValuesBuilder() { - - internal val fieldAndValues: MutableList = mutableListOf() - - override fun String.toEncoded(encodedValue: Any?) { - fieldAndValues += FieldAndValue.WithStringField(this, encodedValue) - } - - override fun FieldPath.toEncoded(encodedValue: Any?) { - fieldAndValues += FieldAndValue.WithFieldPath(this, encodedValue) - } -} From 99806bbe0384c386b9883d17724f1e848a1812c1 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 7 Oct 2024 16:26:27 +0200 Subject: [PATCH 10/19] PR remarks --- README.md | 11 +- .../api/android/firebase-firestore.api | 50 +++---- .../api/jvm/firebase-firestore.api | 50 +++---- .../firebase/firestore/FieldValueBuilder.kt | 25 ---- .../firebase/firestore/FieldValuesDSL.kt | 53 ++++++++ .../firestore/FieldsAndValuesBuilder.kt | 39 ------ .../firestore/FieldsAndValuesUpdateDSL.kt | 89 +++++++++++++ .../gitlive/firebase/firestore/firestore.kt | 124 ++++++++++++------ .../firestore/DocumentReferenceTest.kt | 4 +- .../gitlive/firebase/firestore/QueryTest.kt | 16 +-- .../firebase/firestore/TransactionTest.kt | 2 +- 11 files changed, 291 insertions(+), 172 deletions(-) delete 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/FieldValuesDSL.kt delete 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/FieldsAndValuesUpdateDSL.kt diff --git a/README.md b/README.md index 05d26bffd..e9945537d 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Asynchronous operations that return a single or no value are represented by susp suspend fun signInWithCustomToken(token: String): AuthResult ``` -It is important to remember that unlike a callback based API, wating for suspending functions to complete is implicit and so if you don't want to wait for the result you can `launch` a new coroutine: +It is important to remember that unlike a callback based API, waiting for suspending functions to complete is implicit and so if you don't want to wait for the result you can `launch` a new coroutine: ```kotlin //TODO don't use GlobalScope @@ -209,8 +209,6 @@ user.updateProfile(profileUpdates) user.updateProfile(displayName = "Jane Q. User", photoURL = "https://example.com/jane-q-user/profile.jpg") ``` - -

Infix notation

To improve readability and reduce boilerplate for functions such as the Cloud Firestore query operators are built with infix notation: @@ -241,13 +239,18 @@ citiesRef.where { } ``` -Similar methods exist for `update` methods in the Firestore module: +Similar methods exist for `update`/`startAt`/`startAfter`/`endAt`/`endBefore` methods in the Firestore module: ```kotlin documentRef.update { "field" to "value" "otherField".to(IntAsStringSerializer(), 1) } + +query.orderBy("field", "otherField").startAt { // similar syntax for startAfter/endAt/endBefore + add("Value") + add(1, IntAsStringSerializer()) +} ```

Operator overloading

diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index 9cf847e6b..50a8e7fed 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/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 updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -160,13 +160,6 @@ 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; @@ -176,7 +169,14 @@ 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 class dev/gitlive/firebase/firestore/FieldValuesDSL { + 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/FieldsAndValuesUpdateDSL { 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 @@ -441,13 +441,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 (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 endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAtFieldValues (Lkotlin/jvm/functions/Function1;)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 (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 endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBeforeFieldValues (Lkotlin/jvm/functions/Function1;)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; @@ -459,13 +459,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 (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 startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfterFieldValues (Lkotlin/jvm/functions/Function1;)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 (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 startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAtFieldValues (Lkotlin/jvm/functions/Function1;)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/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 updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)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 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/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 updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)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 final fun updateFields (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 6b5abda69..1deee3348 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/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 updateFieldPaths ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields (Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun updateFields ([Lkotlin/Pair;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun updateFields ([Lkotlin/Pair;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } public final class dev/gitlive/firebase/firestore/DocumentReference$Companion { @@ -160,13 +160,6 @@ 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; @@ -176,7 +169,14 @@ 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 class dev/gitlive/firebase/firestore/FieldValuesDSL { + 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/FieldsAndValuesUpdateDSL { 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 @@ -441,13 +441,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 (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 endAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun endAtFieldValues (Lkotlin/jvm/functions/Function1;)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 (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 endBefore ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun endBeforeFieldValues (Lkotlin/jvm/functions/Function1;)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; @@ -459,13 +459,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 (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 startAfter ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAfterFieldValues (Lkotlin/jvm/functions/Function1;)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 (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 startAt ([Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Query; + public final fun startAtFieldValues (Lkotlin/jvm/functions/Function1;)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/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 updateFieldPaths (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; + public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Transaction; public final fun updateFields (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)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 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/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 updateField (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/WriteBatch; public final fun updateFieldPath (Ldev/gitlive/firebase/firestore/DocumentReference;[Lkotlin/Pair;)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 final fun updateFields (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/FieldValueBuilder.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt deleted file mode 100644 index 53d5a0d13..000000000 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValueBuilder.kt +++ /dev/null @@ -1,25 +0,0 @@ -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/FieldValuesDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt new file mode 100644 index 000000000..f0d851a42 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt @@ -0,0 +1,53 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.EncodeSettings +import kotlinx.serialization.SerializationStrategy + +/** + * A builder for generating the field values of a [Query]. + * The order of the field values must match the order by clauses of the [Query] + */ +public class FieldValuesDSL internal constructor() { + + internal val fieldValues: MutableList = mutableListOf() + + /** + * The [EncodeSettings.Builder] to apply to the next field values added. + * Updating this value will only influence the encoding of field values not yet added to the update. + * This allows for custom encoding per value, e.g. + * + * ``` + * buildSettings = { encodeDefaults = true } + * add(ClassWithDefaults()) + * buildSettings = { encodeDefaults = false } + * add(ClassWithDefaults()) + * ``` + */ + public var buildSettings: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } + + /** + * Adds a field value to the [Query] + * @param T the type of the value to add + * @param value the value [T] to add + */ + public inline fun add(value: T) { + addEncoded(encode(value, buildSettings)!!) + } + + /** + * Adds a field value to the [Query] + * @param T the type of the value to add + * @param strategy the [SerializationStrategy] to apply to the value + * @param value the value [T] to add + */ + 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 deleted file mode 100644 index aba64b228..000000000 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesBuilder.kt +++ /dev/null @@ -1,39 +0,0 @@ -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/FieldsAndValuesUpdateDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt new file mode 100644 index 000000000..7fca11765 --- /dev/null +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt @@ -0,0 +1,89 @@ +package dev.gitlive.firebase.firestore + +import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.firestore.internal.FieldAndValue +import kotlinx.serialization.SerializationStrategy + +/** + * A builder for generating a collection of updates to a document. + * Updates can be applied to either a String field or to a [FieldPath]. + * Within this builder custom serialization can be applied to the update. + * + * ``` + * val update: FieldsAndValuesUpdateBuilder.() -> Unit = { + * buildSettings = { encodeDefaults = false } + * + * "path" to 1 + * FieldPath("subpath", "field") to "value" + * "otherPath".to(strategy, value) + * } + * ``` + */ +public class FieldsAndValuesUpdateDSL internal constructor() { + + internal val fieldAndValues: MutableList = mutableListOf() + + /** + * The [EncodeSettings.Builder] to apply to the next values added to this update. + * Updating this value will only influence the encoding of values not yet added to the update. + * This allows for custom encoding per update, e.g. + * + * ``` + * buildSettings = { encodeDefaults = true } + * "path" to ClassWithDefaults() + * buildSettings = { encodeDefaults = false } + * "otherPath" to ClassWithDefaults() + * ``` + */ + public var buildSettings: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } + + /** + * Updates the field represented by a String to a given value + * @param T the type of the value + * @param value the value [T] to update to + */ + public inline infix fun String.to(value: T) { + toEncoded(encode(value, buildSettings)) + } + + /** + * Updates a [FieldPath] to a given value + * @param T the type of the value + * @param value the value [T] to update to + */ + public inline infix fun FieldPath.to(value: T) { + toEncoded(encode(value, buildSettings)) + } + + /** + * Updates the field represented by a String to a given value + * @param T the type of the value + * @param strategy the [SerializationStrategy] to apply to the value + * @param value the value [T] to update to + */ + public fun String.to(strategy: SerializationStrategy, value: T) { + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + } + + /** + * Updates a [FieldPath] to a given value + * @param T the type of the value + * @param strategy the [SerializationStrategy] to apply to the value + * @param value the value [T] to update to + */ + 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 c87f4194c..c5a9b493e 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 @@ -193,11 +193,11 @@ public data class Transaction internal constructor(internal val nativeWrapper: N @JvmName("updateFields") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): Transaction = - update(documentRef, {}, *fieldsAndValues) + update(documentRef, *fieldsAndValues) {} @JvmName("updateFields") - public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Transaction = - update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Transaction = + updateFields( documentRef, ) { this.buildSettings = buildSettings @@ -208,11 +208,11 @@ public data class Transaction internal constructor(internal val nativeWrapper: N @JvmName("updateFieldPaths") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): Transaction = - update(documentRef, {}, *fieldsAndValues) + update(documentRef, *fieldsAndValues) {} @JvmName("updateFieldPaths") - public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Transaction = - update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Transaction = + updateFields( documentRef, ) { this.buildSettings = buildSettings @@ -221,10 +221,15 @@ public data class Transaction internal constructor(internal val nativeWrapper: N } } - public fun update( + /** + * Updates Fields/[FieldPath] of a [DocumentReference] using a [FieldsAndValuesUpdateDSL]. + * @param documentRef the [DocumentReference] to update + * @param fieldsAndValuesUpdateDSL closure for configuring the [FieldsAndValuesUpdateDSL] + */ + public fun updateFields( documentRef: DocumentReference, - fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, - ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues)) + fieldsAndValuesUpdateDSL: FieldsAndValuesUpdateDSL.() -> Unit, + ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldAndValues)) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, encodedData)) @@ -254,52 +259,76 @@ 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 = startAfter({}, *fieldValues) - public fun startAfter(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = - startAfter { + public fun startAfter(vararg fieldValues: Any?): Query = startAfter(*fieldValues) {} + public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = + startAfterFieldValues { this.buildSettings = buildSettings fieldValues.forEach { add(it) } } - public fun startAfter(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAfter(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + /** + * Creates and returns a new [Query] that starts after the provided fields relative to the order of the query. + * The field values are configured using a [FieldValuesDSL]. + * The order of the field values must match the order of the [orderBy] clauses of the query + * @param builder closure for configuring the [FieldValuesDSL] + */ + public fun startAfterFieldValues(builder: FieldValuesDSL.() -> Unit): Query = Query(nativeQuery.startAfter(*FieldValuesDSL().apply(builder).fieldValues.toTypedArray())) public fun startAt(document: DocumentSnapshot): Query = Query(nativeQuery.startAt(document.native)) - public fun startAt(vararg fieldValues: Any?): Query = startAt({}, *fieldValues) - public fun startAt(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = - startAt { + public fun startAt(vararg fieldValues: Any?): Query = startAt(*fieldValues) {} + public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = + startAtFieldValues { this.buildSettings = buildSettings fieldValues.forEach { add(it) } } - public fun startAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.startAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + /** + * Creates and returns a new [Query] that starts at the provided fields relative to the order of the query. + * The field values are configured using a [FieldValuesDSL]. + * The order of the field values must match the order of the [orderBy] clauses of the query + * @param builder closure for configuring the [FieldValuesDSL] + */ + public fun startAtFieldValues(builder: FieldValuesDSL.() -> Unit): Query = Query(nativeQuery.startAt(*FieldValuesDSL().apply(builder).fieldValues.toTypedArray())) public fun endBefore(document: DocumentSnapshot): Query = Query(nativeQuery.endBefore(document.native)) - public fun endBefore(vararg fieldValues: Any?): Query = endBefore({}, *fieldValues) - public fun endBefore(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = - endBefore { + public fun endBefore(vararg fieldValues: Any?): Query = endBefore(*fieldValues) {} + public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = + endBeforeFieldValues { this.buildSettings = buildSettings fieldValues.forEach { add(it) } } - public fun endBefore(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endBefore(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + /** + * Creates and returns a new [Query] that ends before the provided fields relative to the order of the query. + * The field values are configured using a [FieldValuesDSL]. + * The order of the field values must match the order of the [orderBy] clauses of the query + * @param builder closure for configuring the [FieldValuesDSL] + */ + public fun endBeforeFieldValues(builder: FieldValuesDSL.() -> Unit): Query = Query(nativeQuery.endBefore(*FieldValuesDSL().apply(builder).fieldValues.toTypedArray())) public fun endAt(document: DocumentSnapshot): Query = Query(nativeQuery.endAt(document.native)) - public fun endAt(vararg fieldValues: Any?): Query = endAt({}, *fieldValues) - public fun endAt(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldValues: Any?): Query = - endAt { + public fun endAt(vararg fieldValues: Any?): Query = endAt(*fieldValues) {} + public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = + endAtFieldValues { this.buildSettings = buildSettings fieldValues.forEach { add(it) } } - public fun endAt(builder: FieldValueBuilder.() -> Unit): Query = Query(nativeQuery.endAt(*FieldValueBuilder().apply(builder).fieldValues.toTypedArray())) + /** + * Creates and returns a new [Query] that ends at the provided fields relative to the order of the query. + * The field values are configured using a [FieldValuesDSL]. + * The order of the field values must match the order of the [orderBy] clauses of the query + * @param builder closure for configuring the [FieldValuesDSL] + */ + public fun endAtFieldValues(builder: FieldValuesDSL.() -> Unit): Query = Query(nativeQuery.endAt(*FieldValuesDSL().apply(builder).fieldValues.toTypedArray())) } @Deprecated("Deprecated in favor of using a [FilterBuilder]", replaceWith = ReplaceWith("where { field equalTo equalTo }", "dev.gitlive.firebase.firestore")) @@ -427,11 +456,11 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na @JvmName("updateField") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): WriteBatch = - update(documentRef, {}, *fieldsAndValues) + update(documentRef, *fieldsAndValues) {} @JvmName("updateField") - public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): WriteBatch = - update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): WriteBatch = + updateFields( documentRef, ) { this.buildSettings = buildSettings @@ -442,11 +471,11 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na @JvmName("updateFieldPath") public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair): WriteBatch = - update(documentRef, {}, *fieldsAndValues) + update(documentRef, *fieldsAndValues) {} @JvmName("updateFieldPath") - public fun update(documentRef: DocumentReference, buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): WriteBatch = - update( + public fun update(documentRef: DocumentReference, vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): WriteBatch = + updateFields( documentRef, ) { this.buildSettings = buildSettings @@ -455,13 +484,18 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na } } - public fun update( + /** + * Updates Fields/[FieldPath] of a [DocumentReference] using a [FieldsAndValuesUpdateDSL]. + * @param documentRef the [DocumentReference] to update + * @param fieldsAndValuesUpdateDSL closure for configuring the [FieldsAndValuesUpdateDSL] + */ + public fun updateFields( documentRef: DocumentReference, - fieldAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, + fieldsAndValuesUpdateDSL: FieldsAndValuesUpdateDSL.() -> Unit, ): WriteBatch = WriteBatch( nativeWrapper.updateEncoded( documentRef, - FieldsAndValuesBuilder().apply(fieldAndValuesBuilder).fieldAndValues, + FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldAndValues, ), ) @@ -606,11 +640,11 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFields") public suspend fun update(vararg fieldsAndValues: Pair): Unit = - update({}, *fieldsAndValues) + update(*fieldsAndValues) {} @JvmName("updateFields") - public suspend fun update(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Unit = - update { + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Unit = + updateFields { this.buildSettings = buildSettings fieldsAndValues.forEach { (field, value) -> field to value @@ -619,21 +653,25 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFieldPaths") public suspend fun update(vararg fieldsAndValues: Pair): Unit = - update({}, *fieldsAndValues) + update(*fieldsAndValues) {} @JvmName("updateFieldPaths") - public suspend fun update(buildSettings: EncodeSettings.Builder.() -> Unit, vararg fieldsAndValues: Pair): Unit = - update { + public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Unit = + updateFields { this.buildSettings = buildSettings fieldsAndValues.forEach { (fieldPath, value) -> fieldPath to value } } - public suspend fun update( - fieldsAndValuesBuilder: FieldsAndValuesBuilder.() -> Unit, + /** + * Updates Fields/[FieldPath] using a [FieldsAndValuesUpdateDSL]. + * @param fieldsAndValuesUpdateDSL closure for configuring the [FieldsAndValuesUpdateDSL] + */ + public suspend fun updateFields( + fieldsAndValuesUpdateDSL: FieldsAndValuesUpdateDSL.() -> Unit, ) { - native.updateEncoded(FieldsAndValuesBuilder().apply(fieldsAndValuesBuilder).fieldAndValues) + native.updateEncoded(FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldAndValues) } public suspend fun delete() { 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 d58024788..1862dba40 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 @@ -205,7 +205,7 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { assertEquals(NestedObject("nested"), dataBefore.nested) assertEquals(600.milliseconds, dataBefore.duration) - doc.update { + doc.updateFields { FirestoreTest::count.name to 5 FieldPath(FirestoreTest::optional.name) to "notNull" FirestoreTest::nested.name.to( @@ -367,7 +367,7 @@ class DocumentReferenceTest : BaseFirebaseFirestoreTest() { // update data val updatedData = DataWithDocumentReference(documentRef2) - document.update { + document.updateFields { FieldPath(DataWithDocumentReference::documentReference.name).to( DocumentReferenceSerializer, updatedData.documentReference, 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 665044bda..c95700acd 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 @@ -446,7 +446,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { val encodedQuery = collection .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedSecondPage = encodedQuery.startAfter { + val encodedSecondPage = encodedQuery.startAfterFieldValues { addWithStrategy(NestedObject.serializer(), NestedObject("eee")) } encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testThree) @@ -462,7 +462,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedMultipleSecondPage = encodedMultipleQuery.startAfter { + val encodedMultipleSecondPage = encodedMultipleQuery.startAfterFieldValues { add(0.0) addWithStrategy(NestedObject.serializer(), NestedObject("ddd")) } @@ -495,7 +495,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { val encodedQuery = collection .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedSecondPage = encodedQuery.startAt { + val encodedSecondPage = encodedQuery.startAtFieldValues { addWithStrategy(NestedObject.serializer(), NestedObject("eee")) } encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testTwo, testThree) @@ -511,7 +511,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedMultipleSecondPage = encodedMultipleQuery.startAt { + val encodedMultipleSecondPage = encodedMultipleQuery.startAtFieldValues { add(0.0) addWithStrategy(NestedObject.serializer(), NestedObject("eee")) } @@ -544,7 +544,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { val encodedQuery = collection .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedSecondPage = encodedQuery.endBefore { + val encodedSecondPage = encodedQuery.endBeforeFieldValues { addWithStrategy(NestedObject.serializer(), NestedObject("eee")) } encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testOne) @@ -560,7 +560,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedMultipleSecondPage = encodedMultipleQuery.endBefore { + val encodedMultipleSecondPage = encodedMultipleQuery.endBeforeFieldValues { add(0.0) addWithStrategy(NestedObject.serializer(), NestedObject("eee")) } @@ -593,7 +593,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { val encodedQuery = collection .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedSecondPage = encodedQuery.endAt { + val encodedSecondPage = encodedQuery.endAtFieldValues { addWithStrategy(NestedObject.serializer(), NestedObject("eee")) } encodedSecondPage.assertDocuments(FirestoreTest.serializer(), testOne, testTwo) @@ -609,7 +609,7 @@ open class QueryTest : BaseFirebaseFirestoreTest() { .orderBy(FieldPath(FirestoreTest::time.name), Direction.ASCENDING) .orderBy(FirestoreTest::nested.name, Direction.ASCENDING) - val encodedMultipleSecondPage = encodedMultipleQuery.endAt { + val encodedMultipleSecondPage = encodedMultipleQuery.endAtFieldValues { add(0.0) addWithStrategy(NestedObject.serializer(), NestedObject("ddd")) } 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 index 5a68d53a8..03684e3d6 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/TransactionTest.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/TransactionTest.kt @@ -25,7 +25,7 @@ class TransactionTest : BaseFirebaseFirestoreTest() { val count = get(document).data(FirestoreTest.serializer()).count if (count < 1) { - update(document) { + updateFields(document) { FirestoreTest::prop1.name to "newProperty" FieldPath(FirestoreTest::count.name) to 5 FirestoreTest::duration.name.to(DurationAsIntSerializer(), 100.milliseconds) From 012f95871eb6d805e77efd73d68a8fff5d174350 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Tue, 8 Oct 2024 09:51:56 +0200 Subject: [PATCH 11/19] Fixed broken test --- .../kotlin/dev/gitlive/firebase/firestore/WriteBatchTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 f5e8ece3f..4eecdfbf9 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 @@ -167,13 +167,13 @@ class WriteBatchTest : BaseFirebaseFirestoreTest() { ) val batch = firestore.batch() - batch.update(doc1) { + batch.updateFields(doc1) { FirestoreTest::prop1.name to "prop1-updated" FieldPath(FirestoreTest::optional.name) to "notNull" FirestoreTest::duration.name.to(DurationAsIntSerializer(), 300.milliseconds) FieldPath(FirestoreTest::nested.name).to(NestedObject.serializer(), NestedObject("nested")) } - batch.update(doc2) { + batch.updateFields(doc2) { FirestoreTest::prop1.name to "prop2-updated" FieldPath(FirestoreTest::optional.name) to "alsoNotNull" FirestoreTest::duration.name.to(DurationAsIntSerializer(), 200.milliseconds) From 818fe3889dc70a0e99147fe92de3d77b4fdcfb1e Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Tue, 8 Oct 2024 09:57:35 +0200 Subject: [PATCH 12/19] Disable QueryTest for android unit tests --- .../kotlin/dev/gitlive/firebase/firestore/QueryTest.kt | 1 + 1 file changed, 1 insertion(+) 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 c95700acd..c8eb919d2 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 @@ -8,6 +8,7 @@ import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.time.Duration.Companion.milliseconds +@IgnoreForAndroidUnitTest open class QueryTest : BaseFirebaseFirestoreTest() { companion object { From 6d72b0d911dbe9dc5c865a0772886f43b17d635c Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Mon, 21 Oct 2024 12:41:36 +0200 Subject: [PATCH 13/19] Expanded documentation --- README.md | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e9945537d..76880b242 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,44 @@ In combination with a `SerialName` specified for the child class, you have full } ``` +

Serialization of Updates

+Firestore contains update methods that allow for multiple fields to be updated at the same time. +This sdk offers special update methods that allow for applying custom serialization to each individual field though an update builder. +Where an `update` method exists, an `updateFields` method will also be available. In this, each value can have its serializer customized: + +```kotlin +documentRef.updateFields { + "field" to "value" + // Set the value of otherField to "1" using a custom Serializer + "otherField".to(IntAsStringSerializer(), 1) + + // Overwrite build settings. All fields added after this will have these build settings applied + buildSettings = { + encodeDefaults = true + serializersModule = module + } + "city" to abstractCity +} +``` + +Similarly, the `Query` methods `startAt`/`startAfter`/`endAt`/`endBefore` have an alternative method in `startAtFieldValues`/`startAfterFieldValues`/`endAtFieldValues`/`endBeforeFieldValues` + +```kotlin +query.orderBy("field", "otherField", "city").startAtFieldValues { // similar syntax for startAfter/endAt/endBefore + add("Value") + + // Starts at "1" for the otherField value + add(1, IntAsStringSerializer()) + + // Overwrite build settings. All field values added after this will have these build settings applied + buildSettings = { + encodeDefaults = true + serializersModule = module + } + add(abstractCity) +} +``` +

Default arguments

To reduce boilerplate, default arguments are used in the places where the Firebase Android SDK employs the builder pattern: @@ -239,20 +277,6 @@ citiesRef.where { } ``` -Similar methods exist for `update`/`startAt`/`startAfter`/`endAt`/`endBefore` methods in the Firestore module: - -```kotlin -documentRef.update { - "field" to "value" - "otherField".to(IntAsStringSerializer(), 1) -} - -query.orderBy("field", "otherField").startAt { // similar syntax for startAfter/endAt/endBefore - add("Value") - add(1, IntAsStringSerializer()) -} -``` -

Operator overloading

In cases where it makes sense, such as Firebase Functions HTTPS Callable, operator overloading is used: From ee3419734e5fe8f963b82b49d05baaec5c70583d Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Wed, 30 Oct 2024 09:57:17 +0100 Subject: [PATCH 14/19] Refactored buildSettings variable to encodeNextWith cli --- README.md | 4 +- .../api/android/firebase-firestore.api | 15 +-- .../api/jvm/firebase-firestore.api | 15 +-- .../firebase/firestore/FieldValuesDSL.kt | 19 ++-- .../firestore/FieldsAndValuesUpdateDSL.kt | 23 +++-- .../dev/gitlive/firebase/firestore/Filter.kt | 99 +++++++++++-------- .../gitlive/firebase/firestore/firestore.kt | 20 ++-- 7 files changed, 114 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 76880b242..89020200b 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ documentRef.updateFields { "otherField".to(IntAsStringSerializer(), 1) // Overwrite build settings. All fields added after this will have these build settings applied - buildSettings = { + encodeNextWith { encodeDefaults = true serializersModule = module } @@ -215,7 +215,7 @@ query.orderBy("field", "otherField", "city").startAtFieldValues { // similar syn add(1, IntAsStringSerializer()) // Overwrite build settings. All field values added after this will have these build settings applied - buildSettings = { + encodeNextWith { encodeDefaults = true serializersModule = module } diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index 50a8e7fed..f843fe52a 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -172,13 +172,15 @@ public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx public final class dev/gitlive/firebase/firestore/FieldValuesDSL { 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 fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V + public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; + public final fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V } public final class dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL { - public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; - public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V + public final fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V + public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; + public final fun setEncodeNextWith (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 @@ -238,9 +240,10 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 encodeNextWith (Lkotlin/jvm/functions/Function1;)V 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 getEncodeNextWith ()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; @@ -260,7 +263,7 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V } public final class dev/gitlive/firebase/firestore/FirebaseFirestore { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 1deee3348..3f1d200c4 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -172,13 +172,15 @@ public final class dev/gitlive/firebase/firestore/FieldValueSerializer : kotlinx public final class dev/gitlive/firebase/firestore/FieldValuesDSL { 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 fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V + public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; + public final fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V } public final class dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL { - public final fun getBuildSettings ()Lkotlin/jvm/functions/Function1; - public final fun setBuildSettings (Lkotlin/jvm/functions/Function1;)V + public final fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V + public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; + public final fun setEncodeNextWith (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 @@ -238,9 +240,10 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 encodeNextWith (Lkotlin/jvm/functions/Function1;)V 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 getEncodeNextWith ()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; @@ -260,7 +263,7 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V } public final class dev/gitlive/firebase/firestore/FirebaseFirestore { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt index f0d851a42..d2f119641 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt @@ -11,20 +11,25 @@ public class FieldValuesDSL internal constructor() { internal val fieldValues: MutableList = mutableListOf() + @PublishedApi + internal var encodeNextWith: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } + /** - * The [EncodeSettings.Builder] to apply to the next field values added. + * Sets the [EncodeSettings.Builder] to apply to the next field values added. * Updating this value will only influence the encoding of field values not yet added to the update. * This allows for custom encoding per value, e.g. * * ``` - * buildSettings = { encodeDefaults = true } + * encodeNextWith { encodeDefaults = true } * add(ClassWithDefaults()) - * buildSettings = { encodeDefaults = false } + * encodeNextWith { encodeDefaults = false } * add(ClassWithDefaults()) * ``` */ - public var buildSettings: EncodeSettings.Builder.() -> Unit = { - encodeDefaults = true + public fun encodeNextWith(builder: EncodeSettings.Builder.() -> Unit) { + encodeNextWith = builder } /** @@ -33,7 +38,7 @@ public class FieldValuesDSL internal constructor() { * @param value the value [T] to add */ public inline fun add(value: T) { - addEncoded(encode(value, buildSettings)!!) + addEncoded(encode(value, encodeNextWith)!!) } /** @@ -43,7 +48,7 @@ public class FieldValuesDSL internal constructor() { * @param value the value [T] to add */ public fun addWithStrategy(strategy: SerializationStrategy, value: T) { - addEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)!!) + addEncoded(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!) } @PublishedApi diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt index 7fca11765..a1280c6fb 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt @@ -23,20 +23,25 @@ public class FieldsAndValuesUpdateDSL internal constructor() { internal val fieldAndValues: MutableList = mutableListOf() + @PublishedApi + internal var encodeNextWith: EncodeSettings.Builder.() -> Unit = { + encodeDefaults = true + } + /** - * The [EncodeSettings.Builder] to apply to the next values added to this update. + * Sets the [EncodeSettings.Builder] to apply to the next values added to this update. * Updating this value will only influence the encoding of values not yet added to the update. * This allows for custom encoding per update, e.g. * * ``` - * buildSettings = { encodeDefaults = true } + * encodeNextWith { encodeDefaults = true } * "path" to ClassWithDefaults() - * buildSettings = { encodeDefaults = false } + * encodeNextWith { encodeDefaults = false } * "otherPath" to ClassWithDefaults() * ``` */ - public var buildSettings: EncodeSettings.Builder.() -> Unit = { - encodeDefaults = true + public fun encodeNextWith(builder: EncodeSettings.Builder.() -> Unit) { + encodeNextWith = builder } /** @@ -45,7 +50,7 @@ public class FieldsAndValuesUpdateDSL internal constructor() { * @param value the value [T] to update to */ public inline infix fun String.to(value: T) { - toEncoded(encode(value, buildSettings)) + toEncoded(encode(value, encodeNextWith)) } /** @@ -54,7 +59,7 @@ public class FieldsAndValuesUpdateDSL internal constructor() { * @param value the value [T] to update to */ public inline infix fun FieldPath.to(value: T) { - toEncoded(encode(value, buildSettings)) + toEncoded(encode(value, encodeNextWith)) } /** @@ -64,7 +69,7 @@ public class FieldsAndValuesUpdateDSL internal constructor() { * @param value the value [T] to update to */ public fun String.to(strategy: SerializationStrategy, value: T) { - toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)) } /** @@ -74,7 +79,7 @@ public class FieldsAndValuesUpdateDSL internal constructor() { * @param value the value [T] to update to */ public fun FieldPath.to(strategy: SerializationStrategy, value: T) { - toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, buildSettings)) + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)) } @PublishedApi 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 3f5785c9f..ee9004fda 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 @@ -41,192 +41,209 @@ public sealed class Filter { public class FilterBuilder internal constructor() { - public var buildSettings: EncodeSettings.Builder.() -> Unit = { + @PublishedApi + internal var encodeNextWith: EncodeSettings.Builder.() -> Unit = { encodeDefaults = true } + /** + * Sets the [EncodeSettings.Builder] to apply to the next [WhereConstraint] added. + * Updating this value will only influence the encoding of [WhereConstraint] not yet added to the update. + * This allows for custom encoding per value, e.g. + * + * ``` + * encodeNextWith { encodeDefaults = true } + * "path" equalTo value + * encodeNextWith { encodeDefaults = false } + * "otherPath" equalTo otherValue + * ``` + */ + public fun encodeNextWith(builder: EncodeSettings.Builder.() -> Unit) { + encodeNextWith = builder + } + 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, encodeNextWith)), ) 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, encodeNextWith)), ) 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, encodeNextWith)), ) 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, encodeNextWith)), ) 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, encodeNextWith)), ) 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, encodeNextWith)), ) 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, encodeNextWith)), ) 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, encodeNextWith)), ) public inline infix fun String.lessThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(encode(value, buildSettings)!!), + WhereConstraint.LessThan(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun FieldPath.lessThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(encode(value, buildSettings)!!), + WhereConstraint.LessThan(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun String.greaterThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(encode(value, buildSettings)!!), + WhereConstraint.GreaterThan(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun FieldPath.greaterThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(encode(value, buildSettings)!!), + WhereConstraint.GreaterThan(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun String.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!), + WhereConstraint.LessThanOrEqualTo(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun FieldPath.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(encode(value, buildSettings)!!), + WhereConstraint.LessThanOrEqualTo(encode(value, encodeNextWith)!!), ) public fun FieldPath.lessThanOrEqualTo(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, encodeNextWith)!!), ) public inline infix fun String.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!), + WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun FieldPath.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, buildSettings)!!), + WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeNextWith)!!), ) public fun FieldPath.greaterThanOrEqualTo(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, encodeNextWith)!!), ) public inline infix fun String.contains(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(encode(value, buildSettings)!!), + WhereConstraint.ArrayContains(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) public inline infix fun FieldPath.contains(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(encode(value, buildSettings)!!), + WhereConstraint.ArrayContains(encode(value, encodeNextWith)!!), ) 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, encodeNextWith)!!), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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, encodeNextWith)!! }), ) 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 c5a9b493e..b030660cf 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 @@ -200,7 +200,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N updateFields( documentRef, ) { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -215,7 +215,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N updateFields( documentRef, ) { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -262,7 +262,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun startAfter(vararg fieldValues: Any?): Query = startAfter(*fieldValues) {} public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = startAfterFieldValues { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldValues.forEach { add(it) } @@ -280,7 +280,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun startAt(vararg fieldValues: Any?): Query = startAt(*fieldValues) {} public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = startAtFieldValues { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldValues.forEach { add(it) } @@ -298,7 +298,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun endBefore(vararg fieldValues: Any?): Query = endBefore(*fieldValues) {} public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = endBeforeFieldValues { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldValues.forEach { add(it) } @@ -316,7 +316,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun endAt(vararg fieldValues: Any?): Query = endAt(*fieldValues) {} public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = endAtFieldValues { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldValues.forEach { add(it) } @@ -463,7 +463,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na updateFields( documentRef, ) { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -478,7 +478,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na updateFields( documentRef, ) { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldsAndValues.forEach { (path, value) -> path to value } @@ -645,7 +645,7 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFields") public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Unit = updateFields { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -658,7 +658,7 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFieldPaths") public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Unit = updateFields { - this.buildSettings = buildSettings + encodeNextWith(buildSettings) fieldsAndValues.forEach { (fieldPath, value) -> fieldPath to value } From 59fb0fdbfdd2a69f0c93a2d0c1397f7d75484f5b Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Thu, 14 Nov 2024 00:44:11 +0100 Subject: [PATCH 15/19] Use different encodeSettings approach --- README.md | 12 +- .../api/android/firebase-common.api | 5 + firebase-common/api/jvm/firebase-common.api | 5 + .../gitlive/firebase/EncodeDecodeSettings.kt | 9 ++ .../api/android/firebase-firestore.api | 42 +++--- .../api/jvm/firebase-firestore.api | 42 +++--- .../firebase/firestore/FieldValuesDSL.kt | 52 +++---- .../firestore/FieldsAndValuesUpdateDSL.kt | 74 +++++----- .../dev/gitlive/firebase/firestore/Filter.kt | 134 ++++++++++-------- .../gitlive/firebase/firestore/firestore.kt | 33 +++-- 10 files changed, 237 insertions(+), 171 deletions(-) diff --git a/README.md b/README.md index 47342ceb0..ede0080eb 100644 --- a/README.md +++ b/README.md @@ -196,12 +196,12 @@ documentRef.updateFields { // Set the value of otherField to "1" using a custom Serializer "otherField".to(IntAsStringSerializer(), 1) - // Overwrite build settings. All fields added after this will have these build settings applied - encodeNextWith { + // Overwrite build settings. All fields added within this block will have these build settings applied + withEncodeSettings { encodeDefaults = true serializersModule = module + "city" to abstractCity } - "city" to abstractCity } ``` @@ -214,12 +214,12 @@ query.orderBy("field", "otherField", "city").startAtFieldValues { // similar syn // Starts at "1" for the otherField value add(1, IntAsStringSerializer()) - // Overwrite build settings. All field values added after this will have these build settings applied - encodeNextWith { + // Overwrite build settings. All field values added within this block will have these build settings applied + withEncodeSettings { encodeDefaults = true serializersModule = module + add(abstractCity) } - add(abstractCity) } ``` diff --git a/firebase-common/api/android/firebase-common.api b/firebase-common/api/android/firebase-common.api index 14df6bc61..789d376fd 100644 --- a/firebase-common/api/android/firebase-common.api +++ b/firebase-common/api/android/firebase-common.api @@ -13,6 +13,11 @@ public abstract interface class dev/gitlive/firebase/EncodeDecodeSettings { public abstract interface class dev/gitlive/firebase/EncodeDecodeSettingsBuilder : dev/gitlive/firebase/DecodeSettings$Builder, dev/gitlive/firebase/EncodeSettings$Builder { } +public final class dev/gitlive/firebase/EncodeDecodeSettingsKt { + public static final fun copyFrom (Ldev/gitlive/firebase/DecodeSettings$Builder;Ldev/gitlive/firebase/DecodeSettings$Builder;)V + public static final fun copyFrom (Ldev/gitlive/firebase/EncodeSettings$Builder;Ldev/gitlive/firebase/EncodeSettings$Builder;)V +} + public abstract interface class dev/gitlive/firebase/EncodeSettings : dev/gitlive/firebase/EncodeDecodeSettings { public abstract fun getEncodeDefaults ()Z } diff --git a/firebase-common/api/jvm/firebase-common.api b/firebase-common/api/jvm/firebase-common.api index 14df6bc61..789d376fd 100644 --- a/firebase-common/api/jvm/firebase-common.api +++ b/firebase-common/api/jvm/firebase-common.api @@ -13,6 +13,11 @@ public abstract interface class dev/gitlive/firebase/EncodeDecodeSettings { public abstract interface class dev/gitlive/firebase/EncodeDecodeSettingsBuilder : dev/gitlive/firebase/DecodeSettings$Builder, dev/gitlive/firebase/EncodeSettings$Builder { } +public final class dev/gitlive/firebase/EncodeDecodeSettingsKt { + public static final fun copyFrom (Ldev/gitlive/firebase/DecodeSettings$Builder;Ldev/gitlive/firebase/DecodeSettings$Builder;)V + public static final fun copyFrom (Ldev/gitlive/firebase/EncodeSettings$Builder;Ldev/gitlive/firebase/EncodeSettings$Builder;)V +} + public abstract interface class dev/gitlive/firebase/EncodeSettings : dev/gitlive/firebase/EncodeDecodeSettings { public abstract fun getEncodeDefaults ()Z } diff --git a/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/EncodeDecodeSettings.kt b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/EncodeDecodeSettings.kt index d73b9ede0..23f8456cc 100644 --- a/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/EncodeDecodeSettings.kt +++ b/firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/EncodeDecodeSettings.kt @@ -27,6 +27,11 @@ public interface EncodeSettings : EncodeDecodeSettings { } } +public fun EncodeSettings.Builder.copyFrom(other: EncodeSettings.Builder) { + encodeDefaults = other.encodeDefaults + serializersModule = other.serializersModule +} + /** * [EncodeDecodeSettings] used when decoding an object * @param serializersModule the [SerializersModule] to use for deserialization. This allows for polymorphic serialization on runtime @@ -38,6 +43,10 @@ public interface DecodeSettings : EncodeDecodeSettings { } } +public fun DecodeSettings.Builder.copyFrom(other: DecodeSettings.Builder) { + serializersModule = other.serializersModule +} + public interface EncodeDecodeSettingsBuilder : EncodeSettings.Builder, DecodeSettings.Builder diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index f843fe52a..f446276bd 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -169,22 +169,27 @@ 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/FieldValuesDSL { - public final fun addEncoded (Ljava/lang/Object;)V +public final class dev/gitlive/firebase/firestore/FieldValuesDSL : dev/gitlive/firebase/EncodeSettings$Builder { public final fun addWithStrategy (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V - public final fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V - public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; - public final fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V -} - -public final class dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL { - public final fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V - public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; - public final fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V + public fun getEncodeDefaults ()Z + public final fun getFieldValuesToAdd ()Ljava/util/List; + public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; + public fun setEncodeDefaults (Z)V + public fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V + public final fun withEncodeSettings (Lkotlin/jvm/functions/Function1;)V +} + +public final class dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL : dev/gitlive/firebase/EncodeSettings$Builder { + public fun getEncodeDefaults ()Z + public final fun getFieldAndValueToAdd ()Ljava/util/List; + public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; + public fun setEncodeDefaults (Z)V + public fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)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 final fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/internal/FieldAndValue$WithFieldPath; + public final fun toEncoded (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/internal/FieldAndValue$WithStringField; + public final fun withEncodeSettings (Lkotlin/jvm/functions/Function1;)V } public abstract class dev/gitlive/firebase/firestore/Filter { @@ -232,7 +237,7 @@ public abstract class dev/gitlive/firebase/firestore/Filter$WithConstraint : dev public abstract fun getConstraint ()Ldev/gitlive/firebase/firestore/WhereConstraint; } -public final class dev/gitlive/firebase/firestore/FilterBuilder { +public final class dev/gitlive/firebase/firestore/FilterBuilder : dev/gitlive/firebase/EncodeSettings$Builder { 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; @@ -240,10 +245,11 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 encodeNextWith (Lkotlin/jvm/functions/Function1;)V 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 getEncodeNextWith ()Lkotlin/jvm/functions/Function1; + public fun getEncodeDefaults ()Z + public final fun getEncodeSettingsBuilder ()Lkotlin/jvm/functions/Function1; + public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 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; @@ -263,7 +269,9 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V + public fun setEncodeDefaults (Z)V + public fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V + public final fun withEncoder (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Filter; } public final class dev/gitlive/firebase/firestore/FirebaseFirestore { diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 3f1d200c4..5b6bc21df 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -169,22 +169,27 @@ 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/FieldValuesDSL { - public final fun addEncoded (Ljava/lang/Object;)V +public final class dev/gitlive/firebase/firestore/FieldValuesDSL : dev/gitlive/firebase/EncodeSettings$Builder { public final fun addWithStrategy (Lkotlinx/serialization/SerializationStrategy;Ljava/lang/Object;)V - public final fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V - public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; - public final fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V -} - -public final class dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL { - public final fun encodeNextWith (Lkotlin/jvm/functions/Function1;)V - public final fun getEncodeNextWith ()Lkotlin/jvm/functions/Function1; - public final fun setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V + public fun getEncodeDefaults ()Z + public final fun getFieldValuesToAdd ()Ljava/util/List; + public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; + public fun setEncodeDefaults (Z)V + public fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V + public final fun withEncodeSettings (Lkotlin/jvm/functions/Function1;)V +} + +public final class dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL : dev/gitlive/firebase/EncodeSettings$Builder { + public fun getEncodeDefaults ()Z + public final fun getFieldAndValueToAdd ()Ljava/util/List; + public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; + public fun setEncodeDefaults (Z)V + public fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)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 final fun toEncoded (Ldev/gitlive/firebase/firestore/FieldPath;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/internal/FieldAndValue$WithFieldPath; + public final fun toEncoded (Ljava/lang/String;Ljava/lang/Object;)Ldev/gitlive/firebase/firestore/internal/FieldAndValue$WithStringField; + public final fun withEncodeSettings (Lkotlin/jvm/functions/Function1;)V } public abstract class dev/gitlive/firebase/firestore/Filter { @@ -232,7 +237,7 @@ public abstract class dev/gitlive/firebase/firestore/Filter$WithConstraint : dev public abstract fun getConstraint ()Ldev/gitlive/firebase/firestore/WhereConstraint; } -public final class dev/gitlive/firebase/firestore/FilterBuilder { +public final class dev/gitlive/firebase/firestore/FilterBuilder : dev/gitlive/firebase/EncodeSettings$Builder { 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; @@ -240,10 +245,11 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 encodeNextWith (Lkotlin/jvm/functions/Function1;)V 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 getEncodeNextWith ()Lkotlin/jvm/functions/Function1; + public fun getEncodeDefaults ()Z + public final fun getEncodeSettingsBuilder ()Lkotlin/jvm/functions/Function1; + public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 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; @@ -263,7 +269,9 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder { 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 setEncodeNextWith (Lkotlin/jvm/functions/Function1;)V + public fun setEncodeDefaults (Z)V + public fun setSerializersModule (Lkotlinx/serialization/modules/SerializersModule;)V + public final fun withEncoder (Lkotlin/jvm/functions/Function1;)Ldev/gitlive/firebase/firestore/Filter; } public final class dev/gitlive/firebase/firestore/FirebaseFirestore { diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt index d2f119641..570a3ea90 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt @@ -1,58 +1,60 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.copyFrom import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.modules.EmptySerializersModule +import kotlinx.serialization.modules.SerializersModule /** * A builder for generating the field values of a [Query]. * The order of the field values must match the order by clauses of the [Query] */ -public class FieldValuesDSL internal constructor() { +public class FieldValuesDSL internal constructor() : EncodeSettings.Builder { - internal val fieldValues: MutableList = mutableListOf() + override var encodeDefaults: Boolean = true + override var serializersModule: SerializersModule = EmptySerializersModule() @PublishedApi - internal var encodeNextWith: EncodeSettings.Builder.() -> Unit = { - encodeDefaults = true - } - - /** - * Sets the [EncodeSettings.Builder] to apply to the next field values added. - * Updating this value will only influence the encoding of field values not yet added to the update. - * This allows for custom encoding per value, e.g. - * - * ``` - * encodeNextWith { encodeDefaults = true } - * add(ClassWithDefaults()) - * encodeNextWith { encodeDefaults = false } - * add(ClassWithDefaults()) - * ``` - */ - public fun encodeNextWith(builder: EncodeSettings.Builder.() -> Unit) { - encodeNextWith = builder + internal val fieldValuesToAdd: MutableList<() -> Any> = mutableListOf() + internal val fieldValues = fieldValuesToAdd.map { valueToEncode -> + valueToEncode.invoke() } /** * Adds a field value to the [Query] + * The [value] will be encoded according to the [EncodeSettings] set by this builder. * @param T the type of the value to add * @param value the value [T] to add */ public inline fun add(value: T) { - addEncoded(encode(value, encodeNextWith)!!) + fieldValuesToAdd.add { + encode(value, { copyFrom(this@FieldValuesDSL) })!! + } } /** * Adds a field value to the [Query] + * The [value] will be encoded according to the [EncodeSettings] set by this builder. * @param T the type of the value to add * @param strategy the [SerializationStrategy] to apply to the value * @param value the value [T] to add */ public fun addWithStrategy(strategy: SerializationStrategy, value: T) { - addEncoded(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!) + fieldValuesToAdd.add { + dev.gitlive.firebase.internal.encode(strategy, value, { copyFrom(this@FieldValuesDSL) })!! + } } - @PublishedApi - internal fun addEncoded(encodedValue: Any) { - fieldValues += encodedValue + /** + * Provides an accessor for encoding values with [EncodeSettings] + * @param dls the [FieldValuesDSL] to specify the [EncodeSettings] and values to add + */ + public fun withEncodeSettings(dls: FieldValuesDSL.() -> Unit) { + fieldValuesToAdd.addAll( + FieldValuesDSL() + .apply { copyFrom(this@FieldValuesDSL) } + .apply(dls).fieldValuesToAdd, + ) } } diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt index a1280c6fb..939ccbba3 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt @@ -1,8 +1,11 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.copyFrom import dev.gitlive.firebase.firestore.internal.FieldAndValue import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.modules.EmptySerializersModule +import kotlinx.serialization.modules.SerializersModule /** * A builder for generating a collection of updates to a document. @@ -11,84 +14,91 @@ import kotlinx.serialization.SerializationStrategy * * ``` * val update: FieldsAndValuesUpdateBuilder.() -> Unit = { - * buildSettings = { encodeDefaults = false } - * * "path" to 1 * FieldPath("subpath", "field") to "value" * "otherPath".to(strategy, value) * } * ``` */ -public class FieldsAndValuesUpdateDSL internal constructor() { +public class FieldsAndValuesUpdateDSL internal constructor() : EncodeSettings.Builder { - internal val fieldAndValues: MutableList = mutableListOf() + override var encodeDefaults: Boolean = true + override var serializersModule: SerializersModule = EmptySerializersModule() @PublishedApi - internal var encodeNextWith: EncodeSettings.Builder.() -> Unit = { - encodeDefaults = true - } - - /** - * Sets the [EncodeSettings.Builder] to apply to the next values added to this update. - * Updating this value will only influence the encoding of values not yet added to the update. - * This allows for custom encoding per update, e.g. - * - * ``` - * encodeNextWith { encodeDefaults = true } - * "path" to ClassWithDefaults() - * encodeNextWith { encodeDefaults = false } - * "otherPath" to ClassWithDefaults() - * ``` - */ - public fun encodeNextWith(builder: EncodeSettings.Builder.() -> Unit) { - encodeNextWith = builder + internal val fieldAndValueToAdd: MutableList<() -> FieldAndValue> = mutableListOf() + internal val fieldsAndValues = fieldAndValueToAdd.map { fieldAndValueToEncode -> + fieldAndValueToEncode.invoke() } /** * Updates the field represented by a String to a given value + * The [value] will be encoded according to the [EncodeSettings] set by this builder. * @param T the type of the value * @param value the value [T] to update to */ public inline infix fun String.to(value: T) { - toEncoded(encode(value, encodeNextWith)) + fieldAndValueToAdd.add { + toEncoded(encode(value, { copyFrom(this@FieldsAndValuesUpdateDSL) })) + } } /** * Updates a [FieldPath] to a given value + * The [value] will be encoded according to the [EncodeSettings] set by this builder. * @param T the type of the value * @param value the value [T] to update to */ public inline infix fun FieldPath.to(value: T) { - toEncoded(encode(value, encodeNextWith)) + fieldAndValueToAdd.add { + toEncoded(encode(value, { copyFrom(this@FieldsAndValuesUpdateDSL) })) + } } /** * Updates the field represented by a String to a given value + * The [value] will be encoded according to the [EncodeSettings] set by this builder. * @param T the type of the value * @param strategy the [SerializationStrategy] to apply to the value * @param value the value [T] to update to */ public fun String.to(strategy: SerializationStrategy, value: T) { - toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)) + fieldAndValueToAdd.add { + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, { copyFrom(this@FieldsAndValuesUpdateDSL) })) + } } /** * Updates a [FieldPath] to a given value + * The [value] will be encoded according to the [EncodeSettings] set by this builder. * @param T the type of the value * @param strategy the [SerializationStrategy] to apply to the value * @param value the value [T] to update to */ public fun FieldPath.to(strategy: SerializationStrategy, value: T) { - toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)) + fieldAndValueToAdd.add { + toEncoded(dev.gitlive.firebase.internal.encode(strategy, value, { copyFrom(this@FieldsAndValuesUpdateDSL) })) + } } - @PublishedApi - internal fun String.toEncoded(encodedValue: Any?) { - fieldAndValues += FieldAndValue.WithStringField(this, encodedValue) + /** + * Provides an accessor for encoding values with [EncodeSettings] + * @param dls the [WithEncoder] to specify the [EncodeSettings] and values to add + */ + public fun withEncodeSettings(dls: FieldsAndValuesUpdateDSL.() -> Unit) { + fieldAndValueToAdd.addAll( + FieldsAndValuesUpdateDSL() + .apply { copyFrom(this@FieldsAndValuesUpdateDSL) } + .apply(dls) + .fieldAndValueToAdd, + ) } @PublishedApi - internal fun FieldPath.toEncoded(encodedValue: Any?) { - fieldAndValues += FieldAndValue.WithFieldPath(this, encodedValue) - } + internal fun String.toEncoded(encodedValue: Any?): FieldAndValue.WithStringField = + FieldAndValue.WithStringField(this, encodedValue) + + @PublishedApi + internal fun FieldPath.toEncoded(encodedValue: Any?): FieldAndValue.WithFieldPath = + FieldAndValue.WithFieldPath(this, encodedValue) } 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 ee9004fda..640c24fdb 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,7 +1,10 @@ package dev.gitlive.firebase.firestore import dev.gitlive.firebase.EncodeSettings +import dev.gitlive.firebase.copyFrom import kotlinx.serialization.SerializationStrategy +import kotlinx.serialization.modules.EmptySerializersModule +import kotlinx.serialization.modules.SerializersModule public sealed interface WhereConstraint { @@ -39,211 +42,224 @@ public sealed class Filter { public data class Path @PublishedApi internal constructor(val path: FieldPath, override val constraint: WhereConstraint) : WithConstraint() } -public class FilterBuilder internal constructor() { +public class FilterBuilder internal constructor() : EncodeSettings.Builder { + + private var _encodeDefaults: Boolean = true + override var encodeDefaults: Boolean + get() = _encodeDefaults + set(value) { + if (_encodeSettingsBuilder.isInitialized()) { + throw IllegalStateException("You should not change encode settings after they've been used. Call withEncoder again") + } else { + _encodeDefaults = value + } + } + private var _serializersModule: SerializersModule = EmptySerializersModule() + override var serializersModule: SerializersModule + get() = _serializersModule + set(value) { + if (_encodeSettingsBuilder.isInitialized()) { + throw IllegalStateException("You should not change encode settings after they've been used. Call withEncoder again") + } else { + _serializersModule = value + } + } - @PublishedApi - internal var encodeNextWith: EncodeSettings.Builder.() -> Unit = { - encodeDefaults = true + private val _encodeSettingsBuilder: Lazy Unit> = lazy { + { + copyFrom(this@FilterBuilder) + } } - /** - * Sets the [EncodeSettings.Builder] to apply to the next [WhereConstraint] added. - * Updating this value will only influence the encoding of [WhereConstraint] not yet added to the update. - * This allows for custom encoding per value, e.g. - * - * ``` - * encodeNextWith { encodeDefaults = true } - * "path" equalTo value - * encodeNextWith { encodeDefaults = false } - * "otherPath" equalTo otherValue - * ``` - */ - public fun encodeNextWith(builder: EncodeSettings.Builder.() -> Unit) { - encodeNextWith = builder - } + @PublishedApi + internal val encodeSettingsBuilder: EncodeSettings.Builder.() -> Unit = _encodeSettingsBuilder.value + + public fun withEncoder(dsl: FilterBuilder.() -> Filter): Filter = FilterBuilder() + .apply { copyFrom(this@FilterBuilder) } + .run(dsl) 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, encodeNextWith)), + WhereConstraint.EqualTo(encode(value, encodeSettingsBuilder)), ) public fun String.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)), + WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), ) 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, encodeNextWith)), + WhereConstraint.EqualTo(encode(value, encodeSettingsBuilder)), ) public fun FieldPath.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)), + WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), ) 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, encodeNextWith)), + WhereConstraint.NotEqualTo(encode(value, encodeSettingsBuilder)), ) public fun String.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)), + WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), ) 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, encodeNextWith)), + WhereConstraint.NotEqualTo(encode(value, encodeSettingsBuilder)), ) public fun FieldPath.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)), + WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), ) public inline infix fun String.lessThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(encode(value, encodeNextWith)!!), + WhereConstraint.LessThan(encode(value, encodeSettingsBuilder)!!), ) public fun String.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun FieldPath.lessThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(encode(value, encodeNextWith)!!), + WhereConstraint.LessThan(encode(value, encodeSettingsBuilder)!!), ) public fun FieldPath.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun String.greaterThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(encode(value, encodeNextWith)!!), + WhereConstraint.GreaterThan(encode(value, encodeSettingsBuilder)!!), ) public fun String.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun FieldPath.greaterThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(encode(value, encodeNextWith)!!), + WhereConstraint.GreaterThan(encode(value, encodeSettingsBuilder)!!), ) public fun FieldPath.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun String.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(encode(value, encodeNextWith)!!), + WhereConstraint.LessThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), ) public fun String.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun FieldPath.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(encode(value, encodeNextWith)!!), + WhereConstraint.LessThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), ) public fun FieldPath.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun String.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeNextWith)!!), + WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), ) public fun String.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun FieldPath.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeNextWith)!!), + WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), ) public fun FieldPath.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun String.contains(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(encode(value, encodeNextWith)!!), + WhereConstraint.ArrayContains(encode(value, encodeSettingsBuilder)!!), ) public fun String.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun FieldPath.contains(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(encode(value, encodeNextWith)!!), + WhereConstraint.ArrayContains(encode(value, encodeSettingsBuilder)!!), ) public fun FieldPath.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, encodeNextWith)!!), + WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), ) public inline infix fun String.containsAny(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContainsAny(values.map { encode(it, encodeNextWith)!! }), + WhereConstraint.ArrayContainsAny(values.map { encode(it, encodeSettingsBuilder)!! }), ) public fun String.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeNextWith)!! }), + WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), ) public inline infix fun FieldPath.containsAny(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContainsAny(values.map { encode(it, encodeNextWith)!! }), + WhereConstraint.ArrayContainsAny(values.map { encode(it, encodeSettingsBuilder)!! }), ) public fun FieldPath.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeNextWith)!! }), + WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), ) public inline infix fun String.inArray(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.InArray(values.map { encode(it, encodeNextWith)!! }), + WhereConstraint.InArray(values.map { encode(it, encodeSettingsBuilder)!! }), ) public fun String.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeNextWith)!! }), + WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), ) public inline infix fun FieldPath.inArray(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.InArray(values.map { encode(it, encodeNextWith)!! }), + WhereConstraint.InArray(values.map { encode(it, encodeSettingsBuilder)!! }), ) public fun FieldPath.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeNextWith)!! }), + WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), ) public inline infix fun String.notInArray(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotInArray(values.map { encode(it, encodeNextWith)!! }), + WhereConstraint.NotInArray(values.map { encode(it, encodeSettingsBuilder)!! }), ) public fun String.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeNextWith)!! }), + WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), ) public inline infix fun FieldPath.notInArray(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotInArray(values.map { encode(it, encodeNextWith)!! }), + WhereConstraint.NotInArray(values.map { encode(it, encodeSettingsBuilder)!! }), ) public fun FieldPath.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeNextWith)!! }), + WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), ) 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 b030660cf..660e4fcd9 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 @@ -200,7 +200,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N updateFields( documentRef, ) { - encodeNextWith(buildSettings) + apply(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -215,7 +215,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N updateFields( documentRef, ) { - encodeNextWith(buildSettings) + apply(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -229,7 +229,7 @@ public data class Transaction internal constructor(internal val nativeWrapper: N public fun updateFields( documentRef: DocumentReference, fieldsAndValuesUpdateDSL: FieldsAndValuesUpdateDSL.() -> Unit, - ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldAndValues)) + ): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldsAndValues)) @PublishedApi internal fun updateEncoded(documentRef: DocumentReference, encodedData: EncodedObject): Transaction = Transaction(nativeWrapper.updateEncoded(documentRef, encodedData)) @@ -262,7 +262,8 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun startAfter(vararg fieldValues: Any?): Query = startAfter(*fieldValues) {} public fun startAfter(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = startAfterFieldValues { - encodeNextWith(buildSettings) + apply(buildSettings) + fieldValues.forEach { add(it) } @@ -280,7 +281,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun startAt(vararg fieldValues: Any?): Query = startAt(*fieldValues) {} public fun startAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = startAtFieldValues { - encodeNextWith(buildSettings) + apply(buildSettings) fieldValues.forEach { add(it) } @@ -298,9 +299,11 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun endBefore(vararg fieldValues: Any?): Query = endBefore(*fieldValues) {} public fun endBefore(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = endBeforeFieldValues { - encodeNextWith(buildSettings) - fieldValues.forEach { - add(it) + withEncodeSettings { + apply(buildSettings) + fieldValues.forEach { + add(it) + } } } @@ -316,7 +319,7 @@ public open class Query internal constructor(internal val nativeQuery: NativeQue public fun endAt(vararg fieldValues: Any?): Query = endAt(*fieldValues) {} public fun endAt(vararg fieldValues: Any?, buildSettings: EncodeSettings.Builder.() -> Unit): Query = endAtFieldValues { - encodeNextWith(buildSettings) + apply(buildSettings) fieldValues.forEach { add(it) } @@ -463,7 +466,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na updateFields( documentRef, ) { - encodeNextWith(buildSettings) + apply(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -478,7 +481,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na updateFields( documentRef, ) { - encodeNextWith(buildSettings) + apply(buildSettings) fieldsAndValues.forEach { (path, value) -> path to value } @@ -495,7 +498,7 @@ public data class WriteBatch internal constructor(internal val nativeWrapper: Na ): WriteBatch = WriteBatch( nativeWrapper.updateEncoded( documentRef, - FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldAndValues, + FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldsAndValues, ), ) @@ -645,7 +648,7 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFields") public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Unit = updateFields { - encodeNextWith(buildSettings) + apply(buildSettings) fieldsAndValues.forEach { (field, value) -> field to value } @@ -658,7 +661,7 @@ public data class DocumentReference internal constructor(internal val native: Na @JvmName("updateFieldPaths") public suspend fun update(vararg fieldsAndValues: Pair, buildSettings: EncodeSettings.Builder.() -> Unit): Unit = updateFields { - encodeNextWith(buildSettings) + apply(buildSettings) fieldsAndValues.forEach { (fieldPath, value) -> fieldPath to value } @@ -671,7 +674,7 @@ public data class DocumentReference internal constructor(internal val native: Na public suspend fun updateFields( fieldsAndValuesUpdateDSL: FieldsAndValuesUpdateDSL.() -> Unit, ) { - native.updateEncoded(FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldAndValues) + native.updateEncoded(FieldsAndValuesUpdateDSL().apply(fieldsAndValuesUpdateDSL).fieldsAndValues) } public suspend fun delete() { From 3a28cbe99babd590d9a419d39b8f85a909c4f715 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Thu, 14 Nov 2024 01:17:37 +0100 Subject: [PATCH 16/19] Fixed actually getting values --- .../kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt | 2 +- .../dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt index 570a3ea90..7c1f4d4a7 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldValuesDSL.kt @@ -17,7 +17,7 @@ public class FieldValuesDSL internal constructor() : EncodeSettings.Builder { @PublishedApi internal val fieldValuesToAdd: MutableList<() -> Any> = mutableListOf() - internal val fieldValues = fieldValuesToAdd.map { valueToEncode -> + internal val fieldValues get() = fieldValuesToAdd.map { valueToEncode -> valueToEncode.invoke() } diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt index 939ccbba3..5ea2ae37d 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/FieldsAndValuesUpdateDSL.kt @@ -27,7 +27,7 @@ public class FieldsAndValuesUpdateDSL internal constructor() : EncodeSettings.Bu @PublishedApi internal val fieldAndValueToAdd: MutableList<() -> FieldAndValue> = mutableListOf() - internal val fieldsAndValues = fieldAndValueToAdd.map { fieldAndValueToEncode -> + internal val fieldsAndValues: List get() = fieldAndValueToAdd.map { fieldAndValueToEncode -> fieldAndValueToEncode.invoke() } From cfb885b33847b61117334f46d2d5cd6386eb0666 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Fri, 15 Nov 2024 10:52:57 +0100 Subject: [PATCH 17/19] Lint fix --- .../kotlin/dev/gitlive/firebase/firestore/Filter.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 640c24fdb..9cef926d6 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,7 +48,7 @@ public class FilterBuilder internal constructor() : EncodeSettings.Builder { override var encodeDefaults: Boolean get() = _encodeDefaults set(value) { - if (_encodeSettingsBuilder.isInitialized()) { + if (lazyEncodeSettingsBuilder.isInitialized()) { throw IllegalStateException("You should not change encode settings after they've been used. Call withEncoder again") } else { _encodeDefaults = value @@ -58,21 +58,21 @@ public class FilterBuilder internal constructor() : EncodeSettings.Builder { override var serializersModule: SerializersModule get() = _serializersModule set(value) { - if (_encodeSettingsBuilder.isInitialized()) { + if (lazyEncodeSettingsBuilder.isInitialized()) { throw IllegalStateException("You should not change encode settings after they've been used. Call withEncoder again") } else { _serializersModule = value } } - private val _encodeSettingsBuilder: Lazy Unit> = lazy { + private val lazyEncodeSettingsBuilder: Lazy Unit> = lazy { { copyFrom(this@FilterBuilder) } } @PublishedApi - internal val encodeSettingsBuilder: EncodeSettings.Builder.() -> Unit = _encodeSettingsBuilder.value + internal val encodeSettingsBuilder: EncodeSettings.Builder.() -> Unit = lazyEncodeSettingsBuilder.value public fun withEncoder(dsl: FilterBuilder.() -> Filter): Filter = FilterBuilder() .apply { copyFrom(this@FilterBuilder) } From 22623090d7cefd5a55c05a2164cb1a79cae3be26 Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Sun, 17 Nov 2024 14:28:45 +0100 Subject: [PATCH 18/19] Corrected Filter implementation --- .../api/android/firebase-firestore.api | 25 +- .../api/jvm/firebase-firestore.api | 25 +- .../dev/gitlive/firebase/firestore/Filter.kt | 266 ++++++++++++------ 3 files changed, 196 insertions(+), 120 deletions(-) diff --git a/firebase-firestore/api/android/firebase-firestore.api b/firebase-firestore/api/android/firebase-firestore.api index f446276bd..acdfb6336 100644 --- a/firebase-firestore/api/android/firebase-firestore.api +++ b/firebase-firestore/api/android/firebase-firestore.api @@ -248,7 +248,6 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder : dev/gitlive/fi 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 fun getEncodeDefaults ()Z - public final fun getEncodeSettingsBuilder ()Lkotlin/jvm/functions/Function1; public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 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; @@ -611,8 +610,7 @@ 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -621,7 +619,6 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContains 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 getValues ()Ljava/util/List; public fun hashCode ()I @@ -629,8 +626,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContainsA } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -650,8 +646,7 @@ public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$F } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -659,8 +654,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThan : } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -669,7 +663,6 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThanOrE 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 getValues ()Ljava/util/List; public fun hashCode ()I @@ -677,8 +670,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$InArray : dev/ } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -686,8 +678,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThan : dev } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -695,8 +686,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThanOrEqua } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -705,7 +695,6 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$NotEqualTo : d 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 getValues ()Ljava/util/List; public fun hashCode ()I diff --git a/firebase-firestore/api/jvm/firebase-firestore.api b/firebase-firestore/api/jvm/firebase-firestore.api index 5b6bc21df..1019894f5 100644 --- a/firebase-firestore/api/jvm/firebase-firestore.api +++ b/firebase-firestore/api/jvm/firebase-firestore.api @@ -248,7 +248,6 @@ public final class dev/gitlive/firebase/firestore/FilterBuilder : dev/gitlive/fi 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 fun getEncodeDefaults ()Z - public final fun getEncodeSettingsBuilder ()Lkotlin/jvm/functions/Function1; public fun getSerializersModule ()Lkotlinx/serialization/modules/SerializersModule; 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; @@ -611,8 +610,7 @@ 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -621,7 +619,6 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContains 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 getValues ()Ljava/util/List; public fun hashCode ()I @@ -629,8 +626,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$ArrayContainsA } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -650,8 +646,7 @@ public abstract interface class dev/gitlive/firebase/firestore/WhereConstraint$F } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -659,8 +654,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThan : } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -669,7 +663,6 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$GreaterThanOrE 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 getValues ()Ljava/util/List; public fun hashCode ()I @@ -677,8 +670,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$InArray : dev/ } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -686,8 +678,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThan : dev } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -695,8 +686,7 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$LessThanOrEqua } 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 (Lkotlin/jvm/functions/Function0;)V public fun equals (Ljava/lang/Object;)Z public fun getValue ()Ljava/lang/Object; public fun hashCode ()I @@ -705,7 +695,6 @@ public final class dev/gitlive/firebase/firestore/WhereConstraint$NotEqualTo : d 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 getValues ()Ljava/util/List; public fun hashCode ()I 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 9cef926d6..53353fda6 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 @@ -19,16 +19,38 @@ public sealed interface WhereConstraint { public val values: List } - 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 data class EqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any?) : ForNullableObject { + override val value: Any? = valueBuilder() + } + + public data class NotEqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any?) : ForNullableObject { + override val value: Any? = valueBuilder() + } + + public data class LessThan @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { + override val value: Any = valueBuilder() + } + public data class GreaterThan @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { + override val value: Any = valueBuilder() + } + public data class LessThanOrEqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { + override val value: Any = valueBuilder() + } + public data class GreaterThanOrEqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { + override val value: Any = valueBuilder() + } + public data class ArrayContains @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { + override val value: Any = valueBuilder() + } + public data class ArrayContainsAny @PublishedApi internal constructor(private val valueBuilders: List<() -> Any>) : ForArray { + override val values: List = valueBuilders.map { it.invoke() } + } + public data class InArray @PublishedApi internal constructor(private val valueBuilders: List<() -> Any>) : ForArray { + override val values: List = valueBuilders.map { it.invoke() } + } + public data class NotInArray @PublishedApi internal constructor(private val valueBuilders: List<() -> Any>) : ForArray { + override val values: List = valueBuilders.map { it.invoke() } + } } public sealed class Filter { @@ -44,222 +66,298 @@ public sealed class Filter { public class FilterBuilder internal constructor() : EncodeSettings.Builder { - private var _encodeDefaults: Boolean = true - override var encodeDefaults: Boolean - get() = _encodeDefaults - set(value) { - if (lazyEncodeSettingsBuilder.isInitialized()) { - throw IllegalStateException("You should not change encode settings after they've been used. Call withEncoder again") - } else { - _encodeDefaults = value - } - } - private var _serializersModule: SerializersModule = EmptySerializersModule() - override var serializersModule: SerializersModule - get() = _serializersModule - set(value) { - if (lazyEncodeSettingsBuilder.isInitialized()) { - throw IllegalStateException("You should not change encode settings after they've been used. Call withEncoder again") - } else { - _serializersModule = value - } - } - - private val lazyEncodeSettingsBuilder: Lazy Unit> = lazy { - { - copyFrom(this@FilterBuilder) - } - } - - @PublishedApi - internal val encodeSettingsBuilder: EncodeSettings.Builder.() -> Unit = lazyEncodeSettingsBuilder.value + override var encodeDefaults: Boolean = true + override var serializersModule: SerializersModule = EmptySerializersModule() public fun withEncoder(dsl: FilterBuilder.() -> Filter): Filter = FilterBuilder() - .apply { copyFrom(this@FilterBuilder) } .run(dsl) - public val String.isNull: Filter.WithConstraint get() = Filter.Field(this, WhereConstraint.EqualTo(null)) + 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, encodeSettingsBuilder)), + WhereConstraint.EqualTo { + encode(value) { copyFrom(this@FilterBuilder) } + }, ) public fun String.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), + WhereConstraint.EqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) } + }, ) - public val FieldPath.isNull: Filter.WithConstraint get() = Filter.Path(this, WhereConstraint.EqualTo(null)) + 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, encodeSettingsBuilder)), + WhereConstraint.EqualTo { + encode(value) { copyFrom(this@FilterBuilder) } + }, ) public fun FieldPath.equalTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.EqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), + WhereConstraint.EqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) } + }, ) - public val String.isNotNull: Filter.WithConstraint get() = Filter.Field(this, WhereConstraint.NotEqualTo(null)) + 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, encodeSettingsBuilder)), + WhereConstraint.NotEqualTo { + encode(value) { copyFrom(this@FilterBuilder) } + }, ) public fun String.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), + WhereConstraint.NotEqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) } + }, ) - public val FieldPath.isNotNull: Filter.WithConstraint get() = Filter.Path(this, WhereConstraint.NotEqualTo(null)) + 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, encodeSettingsBuilder)), + WhereConstraint.NotEqualTo { + encode(value) { copyFrom(this@FilterBuilder) } + }, ) public fun FieldPath.notEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)), + WhereConstraint.NotEqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) } + }, ) public inline infix fun String.lessThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.LessThan { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun String.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.LessThan { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun FieldPath.lessThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.LessThan { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun FieldPath.lessThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.LessThan { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun String.greaterThan(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThan { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun String.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThan { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun FieldPath.greaterThan(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThan { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun FieldPath.greaterThan(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThan(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThan { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun String.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.LessThanOrEqualTo { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun String.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.LessThanOrEqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun FieldPath.lessThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.LessThanOrEqualTo { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun FieldPath.lessThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.LessThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.LessThanOrEqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun String.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThanOrEqualTo { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun String.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThanOrEqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun FieldPath.greaterThanOrEqualTo(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThanOrEqualTo { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun FieldPath.greaterThanOrEqualTo(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.GreaterThanOrEqualTo(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.GreaterThanOrEqualTo { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun String.contains(value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.ArrayContains { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun String.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.ArrayContains { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun FieldPath.contains(value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(encode(value, encodeSettingsBuilder)!!), + WhereConstraint.ArrayContains { + encode(value) { copyFrom(this@FilterBuilder) }!! + }, ) public fun FieldPath.contains(strategy: SerializationStrategy, value: T): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContains(dev.gitlive.firebase.internal.encode(strategy, value, encodeSettingsBuilder)!!), + WhereConstraint.ArrayContains { + dev.gitlive.firebase.internal.encode(strategy, value) { copyFrom(this@FilterBuilder) }!! + }, ) public inline infix fun String.containsAny(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContainsAny(values.map { encode(it, encodeSettingsBuilder)!! }), + WhereConstraint.ArrayContainsAny( + values.map { value -> + { encode(value) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public fun String.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), + WhereConstraint.ArrayContainsAny( + values.map { + { dev.gitlive.firebase.internal.encode(strategy, it) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public inline infix fun FieldPath.containsAny(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContainsAny(values.map { encode(it, encodeSettingsBuilder)!! }), + WhereConstraint.ArrayContainsAny( + values.map { value -> + { encode(value) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public fun FieldPath.containsAny(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.ArrayContainsAny(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), + WhereConstraint.ArrayContainsAny( + values.map { + { dev.gitlive.firebase.internal.encode(strategy, it) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public inline infix fun String.inArray(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.InArray(values.map { encode(it, encodeSettingsBuilder)!! }), + WhereConstraint.InArray( + values.map { value -> + { encode(value) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public fun String.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), + WhereConstraint.InArray( + values.map { + { dev.gitlive.firebase.internal.encode(strategy, it) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public inline infix fun FieldPath.inArray(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.InArray(values.map { encode(it, encodeSettingsBuilder)!! }), + WhereConstraint.InArray( + values.map { value -> + { encode(value) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public fun FieldPath.inArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.InArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), + WhereConstraint.InArray( + values.map { + { dev.gitlive.firebase.internal.encode(strategy, it) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public inline infix fun String.notInArray(values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotInArray(values.map { encode(it, encodeSettingsBuilder)!! }), + WhereConstraint.NotInArray( + values.map { value -> + { encode(value) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public fun String.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Field( this, - WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), + WhereConstraint.NotInArray( + values.map { + { dev.gitlive.firebase.internal.encode(strategy, it) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public inline infix fun FieldPath.notInArray(values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotInArray(values.map { encode(it, encodeSettingsBuilder)!! }), + WhereConstraint.NotInArray( + values.map { value -> + { encode(value) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public fun FieldPath.notInArray(strategy: SerializationStrategy, values: List): Filter.WithConstraint = Filter.Path( this, - WhereConstraint.NotInArray(values.map { dev.gitlive.firebase.internal.encode(strategy, it, encodeSettingsBuilder)!! }), + WhereConstraint.NotInArray( + values.map { + { dev.gitlive.firebase.internal.encode(strategy, it) { copyFrom(this@FilterBuilder) }!! } + }, + ), ) public infix fun Filter.and(right: Filter): Filter.And { From aceb6c188952bc4c4cb3d2afbfb90e470e391e5b Mon Sep 17 00:00:00 2001 From: Gijs van Veen Date: Sun, 17 Nov 2024 14:38:39 +0100 Subject: [PATCH 19/19] Small bugfix on Filter --- .../dev/gitlive/firebase/firestore/Filter.kt | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) 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 53353fda6..ec745f517 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 @@ -15,41 +15,49 @@ public sealed interface WhereConstraint { public sealed interface ForObject : WhereConstraint { public val value: Any } + public sealed interface ForArray : WhereConstraint { public val values: List } public data class EqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any?) : ForNullableObject { - override val value: Any? = valueBuilder() + override val value: Any? get() = valueBuilder() } public data class NotEqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any?) : ForNullableObject { - override val value: Any? = valueBuilder() + override val value: Any? get() = valueBuilder() } public data class LessThan @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { - override val value: Any = valueBuilder() + override val value: Any get() = valueBuilder() } + public data class GreaterThan @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { - override val value: Any = valueBuilder() + override val value: Any get() = valueBuilder() } + public data class LessThanOrEqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { - override val value: Any = valueBuilder() + override val value: Any get() = valueBuilder() } + public data class GreaterThanOrEqualTo @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { - override val value: Any = valueBuilder() + override val value: Any get() = valueBuilder() } + public data class ArrayContains @PublishedApi internal constructor(private val valueBuilder: () -> Any) : ForObject { - override val value: Any = valueBuilder() + override val value: Any get() = valueBuilder() } + public data class ArrayContainsAny @PublishedApi internal constructor(private val valueBuilders: List<() -> Any>) : ForArray { - override val values: List = valueBuilders.map { it.invoke() } + override val values: List get() = valueBuilders.map { it.invoke() } } + public data class InArray @PublishedApi internal constructor(private val valueBuilders: List<() -> Any>) : ForArray { - override val values: List = valueBuilders.map { it.invoke() } + override val values: List get() = valueBuilders.map { it.invoke() } } + public data class NotInArray @PublishedApi internal constructor(private val valueBuilders: List<() -> Any>) : ForArray { - override val values: List = valueBuilders.map { it.invoke() } + override val values: List get() = valueBuilders.map { it.invoke() } } }