1
+ package dev.teamhub.firebase.functions
2
+
3
+ import cocoapods.FirebaseFunctions.*
4
+ import dev.teamhub.firebase.Firebase
5
+ import dev.teamhub.firebase.FirebaseApp
6
+ import dev.teamhub.firebase.FirebaseException
7
+ import kotlinx.serialization.DeserializationStrategy
8
+ import kotlinx.serialization.SerializationStrategy
9
+ import kotlinx.serialization.ImplicitReflectionSerializer
10
+ import dev.teamhub.firebase.decode
11
+ import dev.teamhub.firebase.encode
12
+ import platform.Foundation.*
13
+ import kotlinx.coroutines.CompletableDeferred
14
+
15
+ actual val Firebase .functions
16
+ get() = FirebaseFunctions (FIRFunctions .functions())
17
+
18
+ actual fun Firebase.functions (region : String ) =
19
+ FirebaseFunctions (FIRFunctions .functionsForRegion(region))
20
+
21
+ actual fun Firebase.functions (app : FirebaseApp ) =
22
+ FirebaseFunctions (FIRFunctions .functionsForApp(app.ios))
23
+
24
+ actual fun Firebase.functions (app : FirebaseApp , region : String ) =
25
+ FirebaseFunctions (FIRFunctions .functionsForApp(app.ios, region))
26
+
27
+ actual class FirebaseFunctions internal constructor(val ios : FIRFunctions ) {
28
+ actual fun httpsCallable (name : String , timeout : Long? ) =
29
+ HttpsCallableReference (ios.HTTPSCallableWithName (name).apply { timeout?.let { setTimeoutInterval(it/ 1000.0 ) } })
30
+ }
31
+
32
+ actual class HttpsCallableReference internal constructor(val ios : FIRHTTPSCallable ) {
33
+ actual suspend fun call () = HttpsCallableResult (ios.awaitResult { callWithCompletion(it) })
34
+
35
+ actual suspend inline fun <reified T > call (data : T ) =
36
+ HttpsCallableResult (ios.awaitResult { callWithObject(encode(data), it) })
37
+
38
+ actual suspend inline fun <reified T > call (strategy : SerializationStrategy <T >, data : T ) =
39
+ HttpsCallableResult (ios.awaitResult { callWithObject(encode(strategy, data), it) })
40
+ }
41
+
42
+ actual class HttpsCallableResult constructor(val ios : FIRHTTPSCallableResult ) {
43
+
44
+ actual inline fun <reified T > data () =
45
+ decode<T >(value = ios.data)
46
+
47
+ actual inline fun <reified T > data (strategy : DeserializationStrategy <T >) =
48
+ decode(strategy, ios.data)
49
+ }
50
+
51
+ actual class FirebaseFunctionsException (message : String ): FirebaseException(message)
52
+
53
+ private suspend fun <T > T.await (function : T .(callback: (NSError ? ) -> Unit ) -> Unit ) {
54
+ val job = CompletableDeferred <Unit >()
55
+ function { error ->
56
+ if (error == null ) {
57
+ job.complete(Unit )
58
+ } else {
59
+ job.completeExceptionally(FirebaseFunctionsException (error.toString()))
60
+ }
61
+ }
62
+ job.await()
63
+ }
64
+
65
+ suspend fun <T , R > T.awaitResult (function : T .(callback: (R ? , NSError ? ) -> Unit ) -> Unit ): R {
66
+ val job = CompletableDeferred <R >()
67
+ function { result, error ->
68
+ if (result != null ) {
69
+ job.complete(result)
70
+ } else if (error != null ) {
71
+ job.completeExceptionally(FirebaseFunctionsException (error.toString()))
72
+ }
73
+ }
74
+ return job.await()
75
+ }
0 commit comments