Skip to content

Commit d27b5e4

Browse files
committed
add argument to optionally encode defaults in serialised classes to firebase, functions & database
1 parent e5d4f7a commit d27b5e4

File tree

13 files changed

+261
-264
lines changed
  • firebase-common/src
  • firebase-database/src
    • androidMain/kotlin/dev/gitlive/firebase/database
    • commonMain/kotlin/dev/gitlive/firebase/database
    • jsMain/kotlin/dev/gitlive/firebase/database
  • firebase-firestore/src
  • firebase-functions/src

13 files changed

+261
-264
lines changed

firebase-common/src/androidMain/kotlin/dev/gitlive/firebase/_encoders.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import kotlin.collections.set
1313
actual fun FirebaseEncoder.structureEncoder(desc: SerialDescriptor, vararg typeParams: KSerializer<*>): CompositeEncoder = when(desc.kind as StructureKind) {
1414
StructureKind.LIST -> mutableListOf<Any?>()
1515
.also { value = it }
16-
.let { FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> it.add(index, value) } }
16+
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value -> it.add(index, value) } }
1717
StructureKind.MAP -> mutableListOf<Any?>()
18-
.let { FirebaseCompositeEncoder(positiveInfinity, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } }
18+
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } }
1919
StructureKind.CLASS, StructureKind.OBJECT -> mutableMapOf<Any?, Any?>()
2020
.also { value = it }
21-
.let { FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> it[desc.getElementName(index)] = value } }
21+
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value -> it[desc.getElementName(index)] = value } }
2222
}

firebase-common/src/commonMain/kotlin/dev/gitlive/firebase/encoders.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@ package dev.gitlive.firebase
77
import kotlinx.serialization.*
88
import kotlinx.serialization.modules.EmptyModule
99

10-
fun <T> encode(strategy: SerializationStrategy<T> , value: T, positiveInfinity: Any = Double.POSITIVE_INFINITY): Any? =
11-
FirebaseEncoder(positiveInfinity).apply { encode(strategy, value) }.value//.also { println("encoded $it") }
10+
fun <T> encode(strategy: SerializationStrategy<T>, value: T, shouldEncodeElementDefault: Boolean, positiveInfinity: Any = Double.POSITIVE_INFINITY): Any? =
11+
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply { encode(strategy, value) }.value//.also { println("encoded $it") }
1212

1313
@ImplicitReflectionSerializer
14-
fun encode(value: Any?, positiveInfinity: Any = Double.POSITIVE_INFINITY): Any? = value?.let {
15-
FirebaseEncoder(positiveInfinity).apply { encode(it.firebaseSerializer(), it) }.value
14+
fun encode(value: Any?, shouldEncodeElementDefault: Boolean, positiveInfinity: Any = Double.POSITIVE_INFINITY): Any? = value?.let {
15+
FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply { encode(it.firebaseSerializer(), it) }.value
1616
}
1717

1818
expect fun FirebaseEncoder.structureEncoder(desc: SerialDescriptor, vararg typeParams: KSerializer<*>): CompositeEncoder
1919

20-
class FirebaseEncoder(positiveInfinity: Any) : TimestampEncoder(positiveInfinity), Encoder {
20+
class FirebaseEncoder(internal val shouldEncodeElementDefault: Boolean, positiveInfinity: Any) : TimestampEncoder(positiveInfinity), Encoder {
2121

2222
var value: Any? = null
2323

@@ -87,6 +87,7 @@ abstract class TimestampEncoder(internal val positiveInfinity: Any) {
8787
}
8888

8989
open class FirebaseCompositeEncoder constructor(
90+
private val shouldEncodeElementDefault: Boolean,
9091
positiveInfinity: Any,
9192
private val end: () -> Unit = {},
9293
private val set: (desc: SerialDescriptor, index: Int, value: Any?) -> Unit
@@ -102,15 +103,13 @@ open class FirebaseCompositeEncoder constructor(
102103

103104
override fun endStructure(descriptor: SerialDescriptor) = end()
104105

105-
override fun shouldEncodeElementDefault(descriptor: SerialDescriptor, index: Int): Boolean {
106-
return false
107-
}
106+
override fun shouldEncodeElementDefault(descriptor: SerialDescriptor, index: Int) = shouldEncodeElementDefault
108107

109108
override fun <T : Any> encodeNullableSerializableElement(desc: SerialDescriptor, index: Int, serializer: SerializationStrategy<T>, value: T?) =
110-
set(desc, index, value?.let { FirebaseEncoder(positiveInfinity).apply { encode(serializer, value) }.value })
109+
set(desc, index, value?.let { FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply { encode(serializer, value) }.value })
111110

112111
override fun <T> encodeSerializableElement(desc: SerialDescriptor, index: Int, serializer: SerializationStrategy<T>, value: T) =
113-
set(desc, index, FirebaseEncoder(positiveInfinity).apply { encode(serializer, value) }.value)
112+
set(desc, index, FirebaseEncoder(shouldEncodeElementDefault, positiveInfinity).apply { encode(serializer, value) }.value)
114113

115114
override fun encodeBooleanElement(desc: SerialDescriptor, index: Int, value: Boolean) = set(desc, index, value)
116115

firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/_encoders.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ import kotlin.js.json
1313
actual fun FirebaseEncoder.structureEncoder(desc: SerialDescriptor, vararg typeParams: KSerializer<*>): CompositeEncoder = when(desc.kind as StructureKind) {
1414
StructureKind.LIST -> Array<Any?>(desc.elementsCount) { null }
1515
.also { value = it }
16-
.let { FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> it[index] = value } }
16+
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value -> it[index] = value } }
1717
StructureKind.MAP -> {
1818
val map = json()
1919
var lastKey: String = ""
2020
value = map
21-
FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> if(index % 2 == 0) lastKey = value as String else map[lastKey] = value }
21+
FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value -> if(index % 2 == 0) lastKey = value as String else map[lastKey] = value }
2222
}
2323
StructureKind.CLASS, StructureKind.OBJECT -> json()
2424
.also { value = it }
25-
.let { FirebaseCompositeEncoder(positiveInfinity) { _, index, value -> it[desc.getElementName(index)] = value } }
25+
.let { FirebaseCompositeEncoder(shouldEncodeElementDefault, positiveInfinity) { _, index, value -> it[desc.getElementName(index)] = value } }
2626
}
2727

firebase-database/src/androidMain/kotlin/dev/gitlive/firebase/database/database.kt

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,17 @@ import dev.gitlive.firebase.decode
1616
import kotlinx.coroutines.channels.awaitClose
1717
import kotlinx.coroutines.coroutineScope
1818
import kotlinx.coroutines.flow.callbackFlow
19-
import kotlinx.coroutines.flow.filter
20-
import kotlinx.coroutines.flow.produceIn
2119
import kotlinx.coroutines.selects.select
2220
import kotlinx.coroutines.tasks.asDeferred
2321
import kotlinx.coroutines.tasks.await
2422
import kotlinx.serialization.DeserializationStrategy
2523
import kotlinx.serialization.SerializationStrategy
2624

27-
fun encode(value: Any?) =
28-
dev.gitlive.firebase.encode(value, ServerValue.TIMESTAMP)
25+
fun encode(value: Any?, shouldEncodeElementDefault: Boolean) =
26+
dev.gitlive.firebase.encode(value, shouldEncodeElementDefault, ServerValue.TIMESTAMP)
2927

30-
fun <T> encode(strategy: SerializationStrategy<T> , value: T): Any? =
31-
dev.gitlive.firebase.encode(strategy, value, ServerValue.TIMESTAMP)
28+
fun <T> encode(strategy: SerializationStrategy<T> , value: T, shouldEncodeElementDefault: Boolean): Any? =
29+
dev.gitlive.firebase.encode(strategy, value, shouldEncodeElementDefault, ServerValue.TIMESTAMP)
3230

3331
suspend fun <T> Task<T>.awaitWhileOnline(): T = coroutineScope {
3432

@@ -144,18 +142,18 @@ actual class DatabaseReference internal constructor(
144142
actual fun push() = DatabaseReference(android.push(), persistenceEnabled)
145143
actual fun onDisconnect() = OnDisconnect(android.onDisconnect(), persistenceEnabled)
146144

147-
actual suspend fun setValue(value: Any?) = android.setValue(encode(value))
145+
actual suspend fun setValue(value: Any?, encodeDefaults: Boolean) = android.setValue(encode(value, encodeDefaults))
148146
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
149147
.run { Unit }
150148

151-
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T) =
152-
android.setValue(encode(strategy, value))
149+
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T, encodeDefaults: Boolean) =
150+
android.setValue(encode(strategy, value, encodeDefaults))
153151
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
154152
.run { Unit }
155153

156154
@Suppress("UNCHECKED_CAST")
157-
actual suspend fun updateChildren(update: Map<String, Any?>) =
158-
android.updateChildren(encode(update) as Map<String, Any?>)
155+
actual suspend fun updateChildren(update: Map<String, Any?>, encodeDefaults: Boolean) =
156+
android.updateChildren(encode(update, encodeDefaults) as Map<String, Any?>)
159157
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
160158
.run { Unit }
161159

@@ -194,18 +192,18 @@ actual class OnDisconnect internal constructor(
194192
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
195193
.run { Unit }
196194

197-
actual suspend fun setValue(value: Any) =
198-
android.setValue(encode(value))
195+
actual suspend fun setValue(value: Any, encodeDefaults: Boolean) =
196+
android.setValue(encode(value, encodeDefaults))
199197
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
200198
.run { Unit }
201199

202-
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T) =
203-
android.setValue(encode(strategy, value))
200+
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T, encodeDefaults: Boolean) =
201+
android.setValue(encode(strategy, value, encodeDefaults))
204202
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
205203
.run { Unit}
206204

207-
actual suspend fun updateChildren(update: Map<String, Any?>) =
208-
android.updateChildren(update.mapValues { (_, it) -> encode(it) })
205+
actual suspend fun updateChildren(update: Map<String, Any?>, encodeDefaults: Boolean) =
206+
android.updateChildren(update.mapValues { (_, it) -> encode(it, encodeDefaults) })
209207
.run { if(persistenceEnabled) await() else awaitWhileOnline() }
210208
.run { Unit }
211209
}

firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/database.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ expect class DatabaseReference : Query {
5959
fun child(path: String): DatabaseReference
6060
fun onDisconnect(): OnDisconnect
6161
@ImplicitReflectionSerializer
62-
suspend fun setValue(value: Any?)
63-
suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T)
62+
suspend fun setValue(value: Any?, encodeDefaults: Boolean = true)
63+
suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T, encodeDefaults: Boolean = true)
6464
@ImplicitReflectionSerializer
65-
suspend fun updateChildren(update: Map<String, Any?>)
65+
suspend fun updateChildren(update: Map<String, Any?>, encodeDefaults: Boolean = true)
6666
suspend fun removeValue()
6767
}
6868

@@ -86,9 +86,9 @@ expect class OnDisconnect {
8686
suspend fun removeValue()
8787
suspend fun cancel()
8888
@ImplicitReflectionSerializer
89-
suspend fun setValue(value: Any)
90-
suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T)
89+
suspend fun setValue(value: Any, encodeDefaults: Boolean = true)
90+
suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T, encodeDefaults: Boolean = true)
9191
@ImplicitReflectionSerializer
92-
suspend fun updateChildren(update: Map<String, Any?>)
92+
suspend fun updateChildren(update: Map<String, Any?>, encodeDefaults: Boolean = true)
9393
}
9494

firebase-database/src/jsMain/kotlin/dev/gitlive/firebase/database/database.kt

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import kotlinx.coroutines.flow.callbackFlow
1111
import kotlinx.serialization.DeserializationStrategy
1212
import kotlinx.serialization.SerializationStrategy
1313

14-
fun encode(value: Any?) =
15-
encode(value, firebase.database.ServerValue.TIMESTAMP)
16-
fun <T> encode(strategy: SerializationStrategy<T> , value: T): Any? =
17-
encode(strategy, value, firebase.database.ServerValue.TIMESTAMP)
14+
fun encode(value: Any?, shouldEncodeElementDefault: Boolean) =
15+
encode(value, shouldEncodeElementDefault, firebase.database.ServerValue.TIMESTAMP)
16+
fun <T> encode(strategy: SerializationStrategy<T>, value: T, shouldEncodeElementDefault: Boolean): Any? =
17+
encode(strategy, value, shouldEncodeElementDefault, firebase.database.ServerValue.TIMESTAMP)
1818

1919

2020
actual val Firebase.database
@@ -92,17 +92,17 @@ actual class DatabaseReference internal constructor(override val js: firebase.da
9292

9393
actual fun onDisconnect() = rethrow { OnDisconnect(js.onDisconnect()) }
9494

95-
actual suspend fun updateChildren(update: Map<String, Any?>) =
96-
rethrow { js.update(encode(update)).await() }
95+
actual suspend fun updateChildren(update: Map<String, Any?>, encodeDefaults: Boolean) =
96+
rethrow { js.update(encode(update, encodeDefaults)).await() }
9797

9898
actual suspend fun removeValue() = rethrow { js.remove().await() }
9999

100-
actual suspend fun setValue(value: Any?) = rethrow {
101-
js.set(encode(value)).await()
100+
actual suspend fun setValue(value: Any?, encodeDefaults: Boolean) = rethrow {
101+
js.set(encode(value, encodeDefaults)).await()
102102
}
103103

104-
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T) =
105-
rethrow { js.set(encode(strategy, value)).await() }
104+
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T, encodeDefaults: Boolean) =
105+
rethrow { js.set(encode(strategy, value, encodeDefaults)).await() }
106106
}
107107

108108
actual class DataSnapshot internal constructor(val js: firebase.database.DataSnapshot) {
@@ -130,14 +130,14 @@ actual class OnDisconnect internal constructor(val js: firebase.database.OnDisco
130130
actual suspend fun removeValue() = rethrow { js.remove().await() }
131131
actual suspend fun cancel() = rethrow { js.cancel().await() }
132132

133-
actual suspend fun updateChildren(update: Map<String, Any?>) =
134-
rethrow { js.update(encode(update)).await() }
133+
actual suspend fun updateChildren(update: Map<String, Any?>, encodeDefaults: Boolean) =
134+
rethrow { js.update(encode(update, encodeDefaults)).await() }
135135

136-
actual suspend fun setValue(value: Any) =
137-
rethrow { js.set(encode(value)).await() }
136+
actual suspend fun setValue(value: Any, encodeDefaults: Boolean) =
137+
rethrow { js.set(encode(value, encodeDefaults)).await() }
138138

139-
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T) =
140-
rethrow { js.set(encode(strategy, value)).await() }
139+
actual suspend fun <T> setValue(strategy: SerializationStrategy<T>, value: T, encodeDefaults: Boolean) =
140+
rethrow { js.set(encode(strategy, value, encodeDefaults)).await() }
141141
}
142142

143143
actual class DatabaseException(error: dynamic) :

0 commit comments

Comments
 (0)