@@ -29,24 +29,27 @@ actual fun Firebase.database(app: FirebaseApp, url: String) =
29
29
rethrow { dev.gitlive.firebase.database; FirebaseDatabase (app.js.database(url)) }
30
30
31
31
actual class FirebaseDatabase internal constructor(val js : firebase.database.Database ) {
32
- actual fun reference (path : String ) = rethrow { DatabaseReference (js.ref(path)) }
33
- actual fun reference () = rethrow { DatabaseReference (js.ref()) }
32
+ actual fun reference (path : String ) = rethrow { DatabaseReference (js.ref(path), js ) }
33
+ actual fun reference () = rethrow { DatabaseReference (js.ref(), js ) }
34
34
actual fun setPersistenceEnabled (enabled : Boolean ) {}
35
35
actual fun setLoggingEnabled (enabled : Boolean ) = rethrow { firebase.database.enableLogging(enabled) }
36
36
actual fun useEmulator (host : String , port : Int ) = rethrow { js.useEmulator(host, port) }
37
37
}
38
38
39
- actual open class Query internal constructor(open val js : firebase.database.Query ) {
39
+ actual open class Query internal constructor(
40
+ open val js : firebase.database.Query ,
41
+ val database : firebase.database.Database
42
+ ) {
40
43
41
- actual fun orderByKey () = Query (js.orderByKey())
42
- actual fun orderByValue () = Query (js.orderByValue())
43
- actual fun orderByChild (path : String ) = Query (js.orderByChild(path))
44
+ actual fun orderByKey () = Query (js.orderByKey(), database )
45
+ actual fun orderByValue () = Query (js.orderByValue(), database )
46
+ actual fun orderByChild (path : String ) = Query (js.orderByChild(path), database )
44
47
45
48
actual val valueEvents get() = callbackFlow<DataSnapshot > {
46
49
val listener = rethrow {
47
50
js.on(
48
51
" value" ,
49
- { it, _ -> trySend(DataSnapshot (it)) },
52
+ { it, _ -> trySend(DataSnapshot (it, database )) },
50
53
{ close(DatabaseException (it)).run { Unit } }
51
54
)
52
55
}
@@ -62,7 +65,7 @@ actual open class Query internal constructor(open val js: firebase.database.Quer
62
65
{ snapshot, previousChildName ->
63
66
trySend(
64
67
ChildEvent (
65
- DataSnapshot (snapshot),
68
+ DataSnapshot (snapshot, database ),
66
69
type,
67
70
previousChildName
68
71
)
@@ -76,51 +79,54 @@ actual open class Query internal constructor(open val js: firebase.database.Quer
76
79
awaitClose { rethrow { listeners.forEach { (eventType, listener) -> js.off(eventType, listener) } } }
77
80
}
78
81
79
- actual fun startAt (value : String , key : String? ) = Query (js.startAt(value, key ? : undefined))
82
+ actual fun startAt (value : String , key : String? ) = Query (js.startAt(value, key ? : undefined), database )
80
83
81
- actual fun startAt (value : Double , key : String? ) = Query (js.startAt(value, key ? : undefined))
84
+ actual fun startAt (value : Double , key : String? ) = Query (js.startAt(value, key ? : undefined), database )
82
85
83
- actual fun startAt (value : Boolean , key : String? ) = Query (js.startAt(value, key ? : undefined))
86
+ actual fun startAt (value : Boolean , key : String? ) = Query (js.startAt(value, key ? : undefined), database )
84
87
85
- actual fun endAt (value : String , key : String? ) = Query (js.endAt(value, key ? : undefined))
88
+ actual fun endAt (value : String , key : String? ) = Query (js.endAt(value, key ? : undefined), database )
86
89
87
- actual fun endAt (value : Double , key : String? ) = Query (js.endAt(value, key ? : undefined))
90
+ actual fun endAt (value : Double , key : String? ) = Query (js.endAt(value, key ? : undefined), database )
88
91
89
- actual fun endAt (value : Boolean , key : String? ) = Query (js.endAt(value, key ? : undefined))
92
+ actual fun endAt (value : Boolean , key : String? ) = Query (js.endAt(value, key ? : undefined), database )
90
93
91
- actual fun limitToFirst (limit : Int ) = Query (js.limitToFirst(limit))
94
+ actual fun limitToFirst (limit : Int ) = Query (js.limitToFirst(limit), database )
92
95
93
- actual fun limitToLast (limit : Int ) = Query (js.limitToLast(limit))
96
+ actual fun limitToLast (limit : Int ) = Query (js.limitToLast(limit), database )
94
97
95
- actual fun equalTo (value : String , key : String? ) = Query (js.equalTo(value, key ? : undefined))
98
+ actual fun equalTo (value : String , key : String? ) = Query (js.equalTo(value, key ? : undefined), database )
96
99
97
- actual fun equalTo (value : Double , key : String? ) = Query (js.equalTo(value, key ? : undefined))
100
+ actual fun equalTo (value : Double , key : String? ) = Query (js.equalTo(value, key ? : undefined), database )
98
101
99
- actual fun equalTo (value : Boolean , key : String? ) = Query (js.equalTo(value, key ? : undefined))
102
+ actual fun equalTo (value : Boolean , key : String? ) = Query (js.equalTo(value, key ? : undefined), database )
100
103
101
104
override fun toString () = js.toString()
102
105
103
106
}
104
107
105
- actual class DatabaseReference internal constructor(override val js : firebase.database.Reference ): Query(js) {
108
+ actual class DatabaseReference internal constructor(
109
+ override val js : firebase.database.Reference ,
110
+ database : firebase.database.Database
111
+ ): Query(js, database) {
106
112
107
113
actual val key get() = rethrow { js.key }
108
- actual fun push () = rethrow { DatabaseReference (js.push()) }
109
- actual fun child (path : String ) = rethrow { DatabaseReference (js.child(path)) }
114
+ actual fun push () = rethrow { DatabaseReference (js.push(), database ) }
115
+ actual fun child (path : String ) = rethrow { DatabaseReference (js.child(path), database ) }
110
116
111
- actual fun onDisconnect () = rethrow { OnDisconnect (js.onDisconnect()) }
117
+ actual fun onDisconnect () = rethrow { OnDisconnect (js.onDisconnect(), database ) }
112
118
113
119
actual suspend fun updateChildren (update : Map <String , Any ?>, encodeDefaults : Boolean ) =
114
- rethrow { js.update(encode(update, encodeDefaults)).awaitWhileOnline() }
120
+ rethrow { js.update(encode(update, encodeDefaults)).awaitWhileOnline(database ) }
115
121
116
- actual suspend fun removeValue () = rethrow { js.remove().awaitWhileOnline() }
122
+ actual suspend fun removeValue () = rethrow { js.remove().awaitWhileOnline(database ) }
117
123
118
124
actual suspend inline fun <reified T > setValue (value : T ? , encodeDefaults : Boolean ) = rethrow {
119
- js.set(encode(value, encodeDefaults)).awaitWhileOnline()
125
+ js.set(encode(value, encodeDefaults)).awaitWhileOnline(database )
120
126
}
121
127
122
128
actual suspend fun <T > setValue (strategy : SerializationStrategy <T >, value : T , encodeDefaults : Boolean ) =
123
- rethrow { js.set(encode(strategy, value, encodeDefaults)).awaitWhileOnline() }
129
+ rethrow { js.set(encode(strategy, value, encodeDefaults)).awaitWhileOnline(database ) }
124
130
125
131
actual suspend fun <T > runTransaction (strategy : KSerializer <T >, transactionUpdate : (currentData: T ) -> T ): DataSnapshot {
126
132
val deferred = CompletableDeferred <DataSnapshot >()
@@ -130,7 +136,7 @@ actual class DatabaseReference internal constructor(override val js: firebase.da
130
136
if (error != null ) {
131
137
deferred.completeExceptionally(error)
132
138
} else {
133
- deferred.complete(DataSnapshot (snapshot!! ))
139
+ deferred.complete(DataSnapshot (snapshot!! , database ))
134
140
}
135
141
},
136
142
applyLocally = false
@@ -140,7 +146,15 @@ actual class DatabaseReference internal constructor(override val js: firebase.da
140
146
141
147
}
142
148
143
- actual class DataSnapshot internal constructor(val js : firebase.database.DataSnapshot ) {
149
+ actual class DataSnapshot internal constructor(
150
+ val js : firebase.database.DataSnapshot ,
151
+ val database : firebase.database.Database
152
+ ) {
153
+
154
+ actual val value get(): Any? {
155
+ check(! hasChildren) { " DataSnapshot.value can only be used for primitive values (snapshots without children)" }
156
+ return js.`val `()
157
+ }
144
158
145
159
actual inline fun <reified T > value () =
146
160
rethrow { decode<T >(value = js.`val `()) }
@@ -150,29 +164,34 @@ actual class DataSnapshot internal constructor(val js: firebase.database.DataSna
150
164
151
165
actual val exists get() = rethrow { js.exists() }
152
166
actual val key get() = rethrow { js.key }
153
- actual fun child (path : String ) = DataSnapshot (js.child(path))
154
-
167
+ actual fun child (path : String ) = DataSnapshot (js.child(path), database )
168
+ actual val hasChildren get() = js.hasChildren()
155
169
actual val children: Iterable <DataSnapshot > = rethrow {
156
170
ArrayList <DataSnapshot >(js.numChildren()).also {
157
- js.forEach { snapshot -> it.add(DataSnapshot (snapshot)) }
171
+ js.forEach { snapshot -> it.add(DataSnapshot (snapshot, database )) }
158
172
}
159
173
}
174
+ actual val ref: DatabaseReference
175
+ get() = DatabaseReference (js.ref, database)
160
176
161
177
}
162
178
163
- actual class OnDisconnect internal constructor(val js : firebase.database.OnDisconnect ) {
179
+ actual class OnDisconnect internal constructor(
180
+ val js : firebase.database.OnDisconnect ,
181
+ val database : firebase.database.Database
182
+ ) {
164
183
165
- actual suspend fun removeValue () = rethrow { js.remove().awaitWhileOnline() }
166
- actual suspend fun cancel () = rethrow { js.cancel().awaitWhileOnline() }
184
+ actual suspend fun removeValue () = rethrow { js.remove().awaitWhileOnline(database ) }
185
+ actual suspend fun cancel () = rethrow { js.cancel().awaitWhileOnline(database ) }
167
186
168
187
actual suspend fun updateChildren (update : Map <String , Any ?>, encodeDefaults : Boolean ) =
169
- rethrow { js.update(encode(update, encodeDefaults)).awaitWhileOnline() }
188
+ rethrow { js.update(encode(update, encodeDefaults)).awaitWhileOnline(database ) }
170
189
171
190
actual suspend inline fun <reified T > setValue (value : T , encodeDefaults : Boolean ) =
172
- rethrow { js.set(encode(value, encodeDefaults)).awaitWhileOnline() }
191
+ rethrow { js.set(encode(value, encodeDefaults)).awaitWhileOnline(database ) }
173
192
174
193
actual suspend fun <T > setValue (strategy : SerializationStrategy <T >, value : T , encodeDefaults : Boolean ) =
175
- rethrow { js.set(encode(strategy, value, encodeDefaults)).awaitWhileOnline() }
194
+ rethrow { js.set(encode(strategy, value, encodeDefaults)).awaitWhileOnline(database ) }
176
195
}
177
196
178
197
actual class DatabaseException actual constructor(message : String? , cause : Throwable ? ) : RuntimeException(message, cause) {
@@ -191,14 +210,12 @@ inline fun <R> rethrow(function: () -> R): R {
191
210
}
192
211
}
193
212
194
- suspend fun <T > Promise<T>.awaitWhileOnline (): T = coroutineScope {
213
+ suspend fun <T > Promise<T>.awaitWhileOnline (database : firebase.database. Database ): T = coroutineScope {
195
214
196
- val notConnected = Firebase . database
215
+ val notConnected = FirebaseDatabase ( database)
197
216
.reference(" .info/connected" )
198
217
.valueEvents
199
- .filter {
200
- ! it.value<Boolean >()
201
- }
218
+ .filter { ! it.value<Boolean >() }
202
219
.produceIn(this )
203
220
204
221
select<T > {
0 commit comments