Skip to content

Commit

Permalink
refactor .js property to an extension
Browse files Browse the repository at this point in the history
  • Loading branch information
nbransby committed May 4, 2024
1 parent 9fe68c2 commit c0463cd
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 60 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ It uses the <a href="https://github.com/GitLiveApp/firebase-java-sdk">Firebase J

### Accessing the underlying Firebase SDK

In some cases you might want to access the underlying official Firebase SDK in platform specific code, for example when the common API is missing the functionality you need. For this purpose each class in the SDK has `android`, `ios` and `js` properties which holds the equivalent object of the underlying official Firebase SDK. For *JVM*, as the `firebase-java-sdk` is a direct port of the Firebase Android SDK, is it also accessed via the `android` property.
In some cases you might want to access the underlying official Firebase SDK in platform specific code, for example when the common API is missing the functionality you need. For this purpose each class in the SDK has `android`, `ios` and `js` extension properties that hold the equivalent object of the underlying official Firebase SDK. For *JVM*, as the `firebase-java-sdk` is a direct port of the Firebase Android SDK, is it also accessed via the `android` property.

These properties are only accessible from the equivalent target's source set. For example to disable persistence in Cloud Firestore on Android you can write the following in your Android specific code (e.g. `androidMain` or `androidTest`):

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ actual fun Firebase.initialize(context: Any?, options: FirebaseOptions, name: St
actual fun Firebase.initialize(context: Any?, options: FirebaseOptions) =
FirebaseApp(initializeApp(options.toJson()))

actual class FirebaseApp internal constructor(val js: JsFirebaseApp) {
val FirebaseApp.js: JsFirebaseApp get() = js

actual class FirebaseApp internal constructor(internal val js: JsFirebaseApp) {
actual val name: String
get() = js.name
actual val options: FirebaseOptions
Expand Down
4 changes: 2 additions & 2 deletions firebase-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gitlive/firebase-auth",
"version": "1.12.0",
"version": "2.0.0",
"description": "Wrapper around firebase for usage in Kotlin Multiplatform projects",
"main": "firebase-auth.js",
"scripts": {
Expand All @@ -23,7 +23,7 @@
},
"homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk",
"dependencies": {
"@gitlive/firebase-app": "1.12.0",
"@gitlive/firebase-app": "2.0.0",
"firebase": "9.19.1",
"kotlin": "1.8.20",
"kotlinx-coroutines-core": "1.6.4"
Expand Down
34 changes: 30 additions & 4 deletions firebase-auth/src/jsMain/kotlin/dev/gitlive/firebase/auth/auth.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,27 @@ import dev.gitlive.firebase.Firebase
import dev.gitlive.firebase.FirebaseApp
import dev.gitlive.firebase.FirebaseException
import dev.gitlive.firebase.FirebaseNetworkException
import dev.gitlive.firebase.auth.externals.*
import dev.gitlive.firebase.auth.externals.Auth
import dev.gitlive.firebase.auth.externals.getAuth
import dev.gitlive.firebase.auth.externals.applyActionCode
import dev.gitlive.firebase.auth.externals.confirmPasswordReset
import dev.gitlive.firebase.auth.externals.createUserWithEmailAndPassword
import dev.gitlive.firebase.auth.externals.sendPasswordResetEmail
import dev.gitlive.firebase.auth.externals.fetchSignInMethodsForEmail
import dev.gitlive.firebase.auth.externals.sendSignInLinkToEmail
import dev.gitlive.firebase.auth.externals.isSignInWithEmailLink
import dev.gitlive.firebase.auth.externals.signInWithEmailAndPassword
import dev.gitlive.firebase.auth.externals.signInWithCustomToken
import dev.gitlive.firebase.auth.externals.signInAnonymously
import dev.gitlive.firebase.auth.externals.signInWithCredential
import dev.gitlive.firebase.auth.externals.signInWithEmailLink
import dev.gitlive.firebase.auth.externals.signOut
import dev.gitlive.firebase.auth.externals.updateCurrentUser
import dev.gitlive.firebase.auth.externals.verifyPasswordResetCode
import dev.gitlive.firebase.auth.externals.checkActionCode
import dev.gitlive.firebase.auth.externals.connectAuthEmulator
import dev.gitlive.firebase.auth.externals.IdTokenResult
import dev.gitlive.firebase.js
import kotlinx.coroutines.await
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
Expand All @@ -21,7 +41,9 @@ actual val Firebase.auth
actual fun Firebase.auth(app: FirebaseApp) =
rethrow { FirebaseAuth(getAuth(app.js)) }

actual class FirebaseAuth internal constructor(val js: Auth) {
val FirebaseAuth.js: Auth get() = js

actual class FirebaseAuth internal constructor(internal val js: Auth) {

actual val currentUser: FirebaseUser?
get() = rethrow { js.currentUser?.let { FirebaseUser(it) } }
Expand Down Expand Up @@ -106,12 +128,16 @@ actual class FirebaseAuth internal constructor(val js: Auth) {
actual fun useEmulator(host: String, port: Int) = rethrow { connectAuthEmulator(js, "http://$host:$port") }
}

actual class AuthResult internal constructor(val js: JsAuthResult) {
val AuthResult.js: JsAuthResult get() = js

actual class AuthResult internal constructor(internal val js: JsAuthResult) {
actual val user: FirebaseUser?
get() = rethrow { js.user?.let { FirebaseUser(it) } }
}

actual class AuthTokenResult(val js: IdTokenResult) {
val AuthTokenResult.js: IdTokenResult get() = js

actual class AuthTokenResult(internal val js: IdTokenResult) {
// actual val authTimestamp: Long
// get() = js.authTime
actual val claims: Map<String, Any>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import dev.gitlive.firebase.auth.externals.EmailAuthProvider
import dev.gitlive.firebase.auth.externals.FacebookAuthProvider
import dev.gitlive.firebase.auth.externals.GithubAuthProvider
import dev.gitlive.firebase.auth.externals.GoogleAuthProvider
import dev.gitlive.firebase.auth.externals.PhoneAuthProvider
import dev.gitlive.firebase.auth.externals.IdTokenResult
import dev.gitlive.firebase.auth.externals.PhoneAuthProvider as JsPhoneAuthProvider
import dev.gitlive.firebase.auth.externals.TwitterAuthProvider
import kotlinx.coroutines.await
import kotlin.js.json
import dev.gitlive.firebase.auth.externals.AuthCredential as JsAuthCredential
import dev.gitlive.firebase.auth.externals.OAuthProvider as JsOAuthProvider

actual open class AuthCredential(val js: JsAuthCredential) {
val AuthCredential.js: JsAuthCredential get() = js

actual open class AuthCredential(internal val js: JsAuthCredential) {
actual val providerId: String
get() = js.providerId
}
Expand Down Expand Up @@ -49,7 +52,9 @@ actual object GoogleAuthProvider {
}
}

actual class OAuthProvider(val js: JsOAuthProvider) {
val OAuthProvider.js: JsOAuthProvider get() = js

actual class OAuthProvider(internal val js: JsOAuthProvider) {

actual constructor(
provider: String,
Expand Down Expand Up @@ -78,11 +83,13 @@ actual class OAuthProvider(val js: JsOAuthProvider) {
}
}

actual class PhoneAuthProvider(val js: PhoneAuthProvider) {
val PhoneAuthProvider.js: JsPhoneAuthProvider get() = js

actual class PhoneAuthProvider(internal val js: JsPhoneAuthProvider) {

actual constructor(auth: FirebaseAuth) : this(PhoneAuthProvider(auth.js))
actual constructor(auth: FirebaseAuth) : this(JsPhoneAuthProvider(auth.js))

actual fun credential(verificationId: String, smsCode: String): PhoneAuthCredential = PhoneAuthCredential(PhoneAuthProvider.credential(verificationId, smsCode))
actual fun credential(verificationId: String, smsCode: String): PhoneAuthCredential = PhoneAuthCredential(JsPhoneAuthProvider.credential(verificationId, smsCode))
actual suspend fun verifyPhoneNumber(phoneNumber: String, verificationProvider: PhoneVerificationProvider): AuthCredential = rethrow {
val verificationId = js.verifyPhoneNumber(phoneNumber, verificationProvider.verifier).await()
val verificationCode = verificationProvider.getVerificationCode(verificationId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import dev.gitlive.firebase.auth.externals.MultiFactorInfo as JsMultiFactorInfo
import dev.gitlive.firebase.auth.externals.MultiFactorResolver as JsMultiFactorResolver
import dev.gitlive.firebase.auth.externals.MultiFactorSession as JsMultiFactorSession

actual class MultiFactor(val js: MultiFactorUser) {
val MultiFactor.js get() = js

actual class MultiFactor(internal val js: MultiFactorUser) {
actual val enrolledFactors: List<MultiFactorInfo>
get() = rethrow { js.enrolledFactors.map { MultiFactorInfo(it) } }
actual suspend fun enroll(multiFactorAssertion: MultiFactorAssertion, displayName: String?) =
Expand All @@ -21,7 +23,9 @@ actual class MultiFactor(val js: MultiFactorUser) {
rethrow { js.unenroll(factorUid).await() }
}

actual class MultiFactorInfo(val js: JsMultiFactorInfo) {
val MultiFactorInfo.js get() = js

actual class MultiFactorInfo(internal val js: JsMultiFactorInfo) {
actual val displayName: String?
get() = rethrow { js.displayName }
actual val enrollmentTime: Double
Expand All @@ -32,14 +36,20 @@ actual class MultiFactorInfo(val js: JsMultiFactorInfo) {
get() = rethrow { js.uid }
}

actual class MultiFactorAssertion(val js: JsMultiFactorAssertion) {
val MultiFactorAssertion.js get() = js

actual class MultiFactorAssertion(internal val js: JsMultiFactorAssertion) {
actual val factorId: String
get() = rethrow { js.factorId }
}

actual class MultiFactorSession(val js: JsMultiFactorSession)
val MultiFactorSession.js get() = js

actual class MultiFactorSession(internal val js: JsMultiFactorSession)

val MultiFactorResolver.js get() = js

actual class MultiFactorResolver(val js: JsMultiFactorResolver) {
actual class MultiFactorResolver(internal val js: JsMultiFactorResolver) {
actual val auth: FirebaseAuth = rethrow { FirebaseAuth(js.auth) }
actual val hints: List<MultiFactorInfo> = rethrow { js.hints.map { MultiFactorInfo(it) } }
actual val session: MultiFactorSession = rethrow { MultiFactorSession(js.session) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import kotlin.js.Date
import dev.gitlive.firebase.auth.externals.UserInfo as JsUserInfo
import kotlin.js.json

actual class FirebaseUser internal constructor(val js: User) {
val FirebaseUser.js get() = js

actual class FirebaseUser internal constructor(internal val js: User) {
actual val uid: String
get() = rethrow { js.uid }
actual val displayName: String?
Expand Down Expand Up @@ -55,7 +57,9 @@ actual class FirebaseUser internal constructor(val js: User) {
actual suspend fun verifyBeforeUpdateEmail(newEmail: String, actionCodeSettings: ActionCodeSettings?) = rethrow { verifyBeforeUpdateEmail(js, newEmail, actionCodeSettings?.toJson()).await() }
}

actual class UserInfo(val js: JsUserInfo) {
val UserInfo.js get() = js

actual class UserInfo(internal val js: JsUserInfo) {
actual val displayName: String?
get() = rethrow { js.displayName }
actual val email: String?
Expand All @@ -70,7 +74,9 @@ actual class UserInfo(val js: JsUserInfo) {
get() = rethrow { js.uid }
}

actual class UserMetaData(val js: UserMetadata) {
val UserMetaData.js get() = js

actual class UserMetaData(internal val js: UserMetadata) {
actual val creationTime: Double?
get() = rethrow {js.creationTime?.let { (Date(it).getTime() / 1000.0) } }
actual val lastSignInTime: Double?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.gitlive.firebase.remoteconfig
import dev.gitlive.firebase.Firebase
import dev.gitlive.firebase.FirebaseApp
import dev.gitlive.firebase.FirebaseException
import dev.gitlive.firebase.js
import dev.gitlive.firebase.remoteconfig.externals.*
import kotlinx.coroutines.await
import kotlin.js.json
Expand All @@ -14,7 +15,9 @@ actual fun Firebase.remoteConfig(app: FirebaseApp): FirebaseRemoteConfig = rethr
FirebaseRemoteConfig(getRemoteConfig(app.js))
}

actual class FirebaseRemoteConfig internal constructor(val js: RemoteConfig) {
val FirebaseRemoteConfig.js get() = js

actual class FirebaseRemoteConfig internal constructor(internal val js: RemoteConfig) {
actual val all: Map<String, FirebaseRemoteConfigValue>
get() = rethrow { getAllKeys().map { Pair(it, getValue(it)) }.toMap() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package dev.gitlive.firebase.remoteconfig

import dev.gitlive.firebase.remoteconfig.externals.Value

actual class FirebaseRemoteConfigValue(val js: Value) {
val FirebaseRemoteConfigValue.js get() = js

actual class FirebaseRemoteConfigValue(internal val js: Value) {
actual fun asBoolean(): Boolean = rethrow { js.asBoolean() }
actual fun asByteArray(): ByteArray = rethrow { js.asString()?.encodeToByteArray() ?: byteArrayOf() }
actual fun asDouble(): Double = rethrow { js.asNumber().toDouble() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import dev.gitlive.firebase.database.externals.ref
import dev.gitlive.firebase.database.externals.remove
import dev.gitlive.firebase.database.externals.set
import dev.gitlive.firebase.database.externals.update
import dev.gitlive.firebase.database.js
import dev.gitlive.firebase.internal.EncodedObject
import dev.gitlive.firebase.internal.decode
import dev.gitlive.firebase.internal.js
import dev.gitlive.firebase.internal.reencodeTransformation
import dev.gitlive.firebase.js
import kotlinx.coroutines.asDeferred
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
Expand All @@ -57,6 +59,7 @@ import dev.gitlive.firebase.database.externals.orderByKey as jsOrderByKey
import dev.gitlive.firebase.database.externals.orderByValue as jsOrderByValue
import dev.gitlive.firebase.database.externals.runTransaction as jsRunTransaction
import dev.gitlive.firebase.database.externals.startAt as jsStartAt
import dev.gitlive.firebase.database.js as publicJs

actual val Firebase.database
get() = rethrow { FirebaseDatabase(getDatabase()) }
Expand All @@ -70,7 +73,9 @@ actual fun Firebase.database(url: String) =
actual fun Firebase.database(app: FirebaseApp, url: String) =
rethrow { FirebaseDatabase(getDatabase(app = app.js, url = url)) }

actual class FirebaseDatabase internal constructor(val js: Database) {
val FirebaseDatabase.js get() = js

actual class FirebaseDatabase internal constructor(internal val js: Database) {

actual fun reference(path: String) = rethrow { DatabaseReference(NativeDatabaseReference(ref(js, path), js)) }
actual fun reference() = rethrow { DatabaseReference(NativeDatabaseReference(ref(js), js)) }
Expand All @@ -89,13 +94,14 @@ internal actual open class NativeQuery(
val database: Database
)

val Query.js: JsQuery get() = nativeQuery.js

actual open class Query internal actual constructor(
nativeQuery: NativeQuery
internal val nativeQuery: NativeQuery
) {

internal constructor(js: JsQuery, database: Database) : this(NativeQuery(js, database))

open val js: JsQuery = nativeQuery.js
val database: Database = nativeQuery.database

actual fun orderByKey() = Query(query(js, jsOrderByKey()), database)
Expand Down Expand Up @@ -196,8 +202,10 @@ internal actual class NativeDatabaseReference internal constructor(
}
}

val DataSnapshot.js: JsDataSnapshot get() = js

actual class DataSnapshot internal constructor(
val js: JsDataSnapshot,
internal val js: JsDataSnapshot,
val database: Database
) {
actual val value get(): Any? {
Expand All @@ -206,10 +214,10 @@ actual class DataSnapshot internal constructor(
}

actual inline fun <reified T> value() =
rethrow { decode<T>(value = js.`val`()) }
rethrow { decode<T>(value = publicJs.`val`()) }

actual inline fun <T> value(strategy: DeserializationStrategy<T>, buildSettings: DecodeSettings.Builder.() -> Unit) =
rethrow { decode(strategy, js.`val`(), buildSettings) }
rethrow { decode(strategy, publicJs.`val`(), buildSettings) }

actual val exists get() = rethrow { js.exists() }
actual val key get() = rethrow { js.key }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import dev.gitlive.firebase.firestore.externals.persistentLocalCache
import dev.gitlive.firebase.firestore.internal.NativeDocumentSnapshotWrapper
import dev.gitlive.firebase.firestore.internal.NativeFirebaseFirestoreWrapper
import dev.gitlive.firebase.firestore.internal.SetOptions
import dev.gitlive.firebase.js
import kotlin.js.Json
import kotlin.js.json
import dev.gitlive.firebase.firestore.externals.Firestore as JsFirestore
Expand Down Expand Up @@ -79,7 +80,7 @@ actual data class FirebaseFirestoreSettings(
}

@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE")
val js: Json get() = json().apply {
internal val js: Json get() = json().apply {
set("ssl", sslEnabled)
set("host", host)
set("localCache",
Expand All @@ -90,11 +91,11 @@ actual data class FirebaseFirestoreSettings(
).asDynamic() as PersistentCacheSettings
)
is LocalCacheSettings.Memory -> {
val garbageCollecorSettings = when (val garbageCollectorSettings = cacheSettings.garbaseCollectorSettings) {
val garbageCollectorSettings = when (val garbageCollectorSettings = cacheSettings.garbaseCollectorSettings) {
is MemoryGarbageCollectorSettings.Eager -> memoryEagerGarbageCollector()
is MemoryGarbageCollectorSettings.LRUGC -> memoryLruGarbageCollector(json("cacheSizeBytes" to garbageCollectorSettings.sizeBytes))
}
memoryLocalCache(json("garbageCollector" to garbageCollecorSettings).asDynamic() as MemoryCacheSettings)
memoryLocalCache(json("garbageCollector" to garbageCollectorSettings).asDynamic() as MemoryCacheSettings)
}
})
}
Expand Down Expand Up @@ -138,15 +139,19 @@ actual class FirebaseFirestoreException(cause: Throwable, val code: FirestoreExc
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
actual val FirebaseFirestoreException.code: FirestoreExceptionCode get() = code

actual class QuerySnapshot(val js: JsQuerySnapshot) {
val QuerySnapshot.js: JsQuerySnapshot get() = js

actual class QuerySnapshot(internal val js: JsQuerySnapshot) {
actual val documents
get() = js.docs.map { DocumentSnapshot(NativeDocumentSnapshotWrapper(it)) }
actual val documentChanges
get() = js.docChanges().map { DocumentChange(it) }
actual val metadata: SnapshotMetadata get() = SnapshotMetadata(js.metadata)
}

actual class DocumentChange(val js: JsDocumentChange) {
val DocumentChange.js: JsDocumentChange get() = js

actual class DocumentChange(internal val js: JsDocumentChange) {
actual val document: DocumentSnapshot
get() = DocumentSnapshot(NativeDocumentSnapshotWrapper(js.doc))
actual val newIndex: Int
Expand All @@ -161,12 +166,16 @@ actual data class NativeDocumentSnapshot(val js: JsDocumentSnapshot)

val DocumentSnapshot.js get() = native.js

actual class SnapshotMetadata(val js: JsSnapshotMetadata) {
val SnapshotMetadata.js get() = js

actual class SnapshotMetadata(internal val js: JsSnapshotMetadata) {
actual val hasPendingWrites: Boolean get() = js.hasPendingWrites
actual val isFromCache: Boolean get() = js.fromCache
}

actual class FieldPath private constructor(val js: JsFieldPath) {
val FieldPath.js get() = js

actual class FieldPath private constructor(internal val js: JsFieldPath) {

actual companion object {
actual val documentId = FieldPath(jsDocumentId())
Expand Down
Loading

0 comments on commit c0463cd

Please sign in to comment.