Skip to content

Commit b29db6f

Browse files
authored
Merge pull request #319 from shepeliev/refactor-web-version-9
Refactor Firebase JS externals using Web v9 modular SDK
2 parents 4aeec01 + 7b78af4 commit b29db6f

File tree

69 files changed

+1500
-1147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1500
-1147
lines changed

firebase-app/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@gitlive/firebase-app",
3-
"version": "1.9.0",
3+
"version": "1.10.0",
44
"description": "Wrapper around firebase for usage in Kotlin Multiplatform projects",
55
"main": "firebase-app.js",
66
"scripts": {
@@ -23,7 +23,7 @@
2323
},
2424
"homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk",
2525
"dependencies": {
26-
"@gitlive/firebase-common": "1.9.0",
26+
"@gitlive/firebase-common": "1.10.0",
2727
"firebase": "9.19.1",
2828
"kotlin": "1.8.20",
2929
"kotlinx-coroutines-core": "1.6.4"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@file:JsModule("firebase/app")
2+
@file:JsNonModule
3+
4+
package dev.gitlive.firebase.externals
5+
6+
import kotlin.js.Promise
7+
8+
external fun initializeApp(options: Any, name: String = definedExternally): FirebaseApp
9+
10+
external fun getApp(name: String = definedExternally): FirebaseApp
11+
12+
external fun getApps(): Array<FirebaseApp>
13+
14+
external fun deleteApp(app: FirebaseApp): Promise<Unit>
15+
16+
external interface FirebaseApp {
17+
val automaticDataCollectionEnabled: Boolean
18+
val name: String
19+
val options: FirebaseOptions
20+
}
21+
22+
external interface FirebaseOptions {
23+
val apiKey: String
24+
val appId : String
25+
val authDomain: String?
26+
val databaseURL: String?
27+
val measurementId: String?
28+
val messagingSenderId: String?
29+
val gaTrackingId: String?
30+
val projectId: String?
31+
val storageBucket: String?
32+
}

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,42 @@
44

55
package dev.gitlive.firebase
66

7+
import dev.gitlive.firebase.externals.deleteApp
8+
import dev.gitlive.firebase.externals.getApp
9+
import dev.gitlive.firebase.externals.getApps
10+
import dev.gitlive.firebase.externals.initializeApp
711
import kotlin.js.json
12+
import dev.gitlive.firebase.externals.FirebaseApp as JsFirebaseApp
813

914
actual val Firebase.app: FirebaseApp
10-
get() = FirebaseApp(firebase.app())
15+
get() = FirebaseApp(getApp())
1116

1217
actual fun Firebase.app(name: String): FirebaseApp =
13-
FirebaseApp(firebase.app(name))
18+
FirebaseApp(getApp(name))
1419

1520
actual fun Firebase.initialize(context: Any?): FirebaseApp? =
1621
throw UnsupportedOperationException("Cannot initialize firebase without options in JS")
1722

1823
actual fun Firebase.initialize(context: Any?, options: FirebaseOptions, name: String): FirebaseApp =
19-
FirebaseApp(firebase.initializeApp(options.toJson(), name))
24+
FirebaseApp(initializeApp(options.toJson(), name))
2025

2126
actual fun Firebase.initialize(context: Any?, options: FirebaseOptions) =
22-
FirebaseApp(firebase.initializeApp(options.toJson()))
27+
FirebaseApp(initializeApp(options.toJson()))
2328

24-
actual class FirebaseApp internal constructor(val js: firebase.App) {
29+
actual class FirebaseApp internal constructor(val js: JsFirebaseApp) {
2530
actual val name: String
2631
get() = js.name
2732
actual val options: FirebaseOptions
2833
get() = js.options.run {
29-
FirebaseOptions(applicationId, apiKey, databaseUrl, gaTrackingId, storageBucket, projectId, messagingSenderId, authDomain)
34+
FirebaseOptions(appId, apiKey, databaseURL, gaTrackingId, storageBucket, projectId, messagingSenderId, authDomain)
3035
}
3136

32-
actual fun delete() = js.delete()
37+
actual fun delete() {
38+
deleteApp(js)
39+
}
3340
}
3441

35-
actual fun Firebase.apps(context: Any?) = firebase.apps.map { FirebaseApp(it) }
42+
actual fun Firebase.apps(context: Any?) = getApps().map { FirebaseApp(it) }
3643

3744
private fun FirebaseOptions.toJson() = json(
3845
"apiKey" to apiKey,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Some tests are fluky in GitHub Actions, so we increase the timeout.
2+
config.set({
3+
client: {
4+
mocha: {
5+
timeout: 5000
6+
}
7+
},
8+
});

firebase-auth/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@gitlive/firebase-auth",
3-
"version": "1.9.0",
3+
"version": "1.10.0",
44
"description": "Wrapper around firebase for usage in Kotlin Multiplatform projects",
55
"main": "firebase-auth.js",
66
"scripts": {
@@ -23,7 +23,7 @@
2323
},
2424
"homepage": "https://github.com/GitLiveApp/firebase-kotlin-sdk",
2525
"dependencies": {
26-
"@gitlive/firebase-app": "1.9.0",
26+
"@gitlive/firebase-app": "1.10.0",
2727
"firebase": "9.19.1",
2828
"kotlin": "1.8.20",
2929
"kotlinx-coroutines-core": "1.6.4"

firebase-auth/src/commonTest/kotlin/dev/gitlive/firebase/auth/auth.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
package dev.gitlive.firebase.auth
66

77
import dev.gitlive.firebase.*
8+
import kotlinx.coroutines.test.TestResult
89
import kotlin.random.Random
910
import kotlin.test.*
1011

1112
expect val emulatorHost: String
1213
expect val context: Any
13-
expect fun runTest(test: suspend () -> Unit)
14+
expect fun runTest(test: suspend () -> Unit): TestResult
1415

1516
class FirebaseAuthTest {
1617

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

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@
55
package dev.gitlive.firebase.auth
66

77
import dev.gitlive.firebase.*
8+
import dev.gitlive.firebase.FirebaseApp
9+
import dev.gitlive.firebase.auth.externals.*
810
import kotlinx.coroutines.await
911
import kotlinx.coroutines.channels.awaitClose
1012
import kotlinx.coroutines.flow.callbackFlow
1113
import kotlin.js.json
14+
import dev.gitlive.firebase.auth.externals.AuthResult as JsAuthResult
1215

1316
actual val Firebase.auth
14-
get() = rethrow { dev.gitlive.firebase.auth; FirebaseAuth(firebase.auth()) }
17+
get() = rethrow { FirebaseAuth(getAuth()) }
1518

1619
actual fun Firebase.auth(app: FirebaseApp) =
17-
rethrow { dev.gitlive.firebase.auth; FirebaseAuth(firebase.auth(app.js)) }
20+
rethrow { FirebaseAuth(getAuth(app.js)) }
1821

19-
actual class FirebaseAuth internal constructor(val js: firebase.auth.Auth) {
22+
actual class FirebaseAuth internal constructor(val js: Auth) {
2023

2124
actual val currentUser: FirebaseUser?
2225
get() = rethrow { js.currentUser?.let { FirebaseUser(it) } }
@@ -39,47 +42,47 @@ actual class FirebaseAuth internal constructor(val js: firebase.auth.Auth) {
3942
get() = js.languageCode ?: ""
4043
set(value) { js.languageCode = value }
4144

42-
actual suspend fun applyActionCode(code: String) = rethrow { js.applyActionCode(code).await() }
43-
actual suspend fun confirmPasswordReset(code: String, newPassword: String) = rethrow { js.confirmPasswordReset(code, newPassword).await() }
45+
actual suspend fun applyActionCode(code: String) = rethrow { applyActionCode(js, code).await() }
46+
actual suspend fun confirmPasswordReset(code: String, newPassword: String) = rethrow { confirmPasswordReset(js, code, newPassword).await() }
4447

4548
actual suspend fun createUserWithEmailAndPassword(email: String, password: String) =
46-
rethrow { AuthResult(js.createUserWithEmailAndPassword(email, password).await()) }
49+
rethrow { AuthResult(createUserWithEmailAndPassword(js, email, password).await()) }
4750

48-
actual suspend fun fetchSignInMethodsForEmail(email: String): List<String> = rethrow { js.fetchSignInMethodsForEmail(email).await().asList() }
51+
actual suspend fun fetchSignInMethodsForEmail(email: String): List<String> = rethrow { fetchSignInMethodsForEmail(js, email).await().asList() }
4952

5053
actual suspend fun sendPasswordResetEmail(email: String, actionCodeSettings: ActionCodeSettings?) =
51-
rethrow { js.sendPasswordResetEmail(email, actionCodeSettings?.toJson()).await() }
54+
rethrow { sendPasswordResetEmail(js, email, actionCodeSettings?.toJson()).await() }
5255

5356
actual suspend fun sendSignInLinkToEmail(email: String, actionCodeSettings: ActionCodeSettings) =
54-
rethrow { js.sendSignInLinkToEmail(email, actionCodeSettings.toJson()).await() }
57+
rethrow { sendSignInLinkToEmail(js, email, actionCodeSettings.toJson()).await() }
5558

56-
actual fun isSignInWithEmailLink(link: String) = rethrow { js.isSignInWithEmailLink(link) }
59+
actual fun isSignInWithEmailLink(link: String) = rethrow { isSignInWithEmailLink(js, link) }
5760

5861
actual suspend fun signInWithEmailAndPassword(email: String, password: String) =
59-
rethrow { AuthResult(js.signInWithEmailAndPassword(email, password).await()) }
62+
rethrow { AuthResult(signInWithEmailAndPassword(js, email, password).await()) }
6063

6164
actual suspend fun signInWithCustomToken(token: String) =
62-
rethrow { AuthResult(js.signInWithCustomToken(token).await()) }
65+
rethrow { AuthResult(signInWithCustomToken(js, token).await()) }
6366

6467
actual suspend fun signInAnonymously() =
65-
rethrow { AuthResult(js.signInAnonymously().await()) }
68+
rethrow { AuthResult(signInAnonymously(js).await()) }
6669

6770
actual suspend fun signInWithCredential(authCredential: AuthCredential) =
68-
rethrow { AuthResult(js.signInWithCredential(authCredential.js).await()) }
71+
rethrow { AuthResult(signInWithCredential(js, authCredential.js).await()) }
6972

7073
actual suspend fun signInWithEmailLink(email: String, link: String) =
71-
rethrow { AuthResult(js.signInWithEmailLink(email, link).await()) }
74+
rethrow { AuthResult(signInWithEmailLink(js, email, link).await()) }
7275

73-
actual suspend fun signOut() = rethrow { js.signOut().await() }
76+
actual suspend fun signOut() = rethrow { signOut(js).await() }
7477

7578
actual suspend fun updateCurrentUser(user: FirebaseUser) =
76-
rethrow { js.updateCurrentUser(user.js).await() }
79+
rethrow { updateCurrentUser(js, user.js).await() }
7780

7881
actual suspend fun verifyPasswordResetCode(code: String): String =
79-
rethrow { js.verifyPasswordResetCode(code).await() }
82+
rethrow { verifyPasswordResetCode(js, code).await() }
8083

8184
actual suspend fun <T : ActionCodeResult> checkActionCode(code: String): T = rethrow {
82-
val result = js.checkActionCode(code).await()
85+
val result = checkActionCode(js, code).await()
8386
@Suppress("UNCHECKED_CAST")
8487
return when(result.operation) {
8588
"EMAIL_SIGNIN" -> ActionCodeResult.SignInWithEmailLink
@@ -98,15 +101,15 @@ actual class FirebaseAuth internal constructor(val js: firebase.auth.Auth) {
98101
} as T
99102
}
100103

101-
actual fun useEmulator(host: String, port: Int) = rethrow { js.useEmulator("http://$host:$port") }
104+
actual fun useEmulator(host: String, port: Int) = rethrow { connectAuthEmulator(js, "http://$host:$port") }
102105
}
103106

104-
actual class AuthResult internal constructor(val js: firebase.auth.AuthResult) {
107+
actual class AuthResult internal constructor(val js: JsAuthResult) {
105108
actual val user: FirebaseUser?
106109
get() = rethrow { js.user?.let { FirebaseUser(it) } }
107110
}
108111

109-
actual class AuthTokenResult(val js: firebase.auth.IdTokenResult) {
112+
actual class AuthTokenResult(val js: IdTokenResult) {
110113
// actual val authTimestamp: Long
111114
// get() = js.authTime
112115
actual val claims: Map<String, Any>
Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,70 @@
11
package dev.gitlive.firebase.auth
22

3-
import dev.gitlive.firebase.firebase
3+
import dev.gitlive.firebase.auth.externals.ApplicationVerifier
4+
import dev.gitlive.firebase.auth.externals.EmailAuthProvider
5+
import dev.gitlive.firebase.auth.externals.FacebookAuthProvider
6+
import dev.gitlive.firebase.auth.externals.GithubAuthProvider
7+
import dev.gitlive.firebase.auth.externals.GoogleAuthProvider
8+
import dev.gitlive.firebase.auth.externals.PhoneAuthProvider
9+
import dev.gitlive.firebase.auth.externals.TwitterAuthProvider
410
import kotlinx.coroutines.await
5-
import kotlin.js.Json
611
import kotlin.js.json
12+
import dev.gitlive.firebase.auth.externals.AuthCredential as JsAuthCredential
13+
import dev.gitlive.firebase.auth.externals.OAuthProvider as JsOAuthProvider
714

8-
actual open class AuthCredential(val js: firebase.auth.AuthCredential) {
15+
actual open class AuthCredential(val js: JsAuthCredential) {
916
actual val providerId: String
1017
get() = js.providerId
1118
}
1219

13-
actual class PhoneAuthCredential(js: firebase.auth.AuthCredential) : AuthCredential(js)
14-
actual class OAuthCredential(js: firebase.auth.AuthCredential) : AuthCredential(js)
20+
actual class PhoneAuthCredential(js: JsAuthCredential) : AuthCredential(js)
21+
actual class OAuthCredential(js: JsAuthCredential) : AuthCredential(js)
1522

1623
actual object EmailAuthProvider {
1724
actual fun credential(email: String, password: String): AuthCredential =
18-
AuthCredential(firebase.auth.EmailAuthProvider.credential(email, password))
25+
AuthCredential(EmailAuthProvider.credential(email, password))
1926

2027
actual fun credentialWithLink(
2128
email: String,
2229
emailLink: String
23-
): AuthCredential = AuthCredential(firebase.auth.EmailAuthProvider.credentialWithLink(email, emailLink))
30+
): AuthCredential = AuthCredential(EmailAuthProvider.credentialWithLink(email, emailLink))
2431
}
2532

2633
actual object FacebookAuthProvider {
2734
actual fun credential(accessToken: String): AuthCredential =
28-
AuthCredential(firebase.auth.FacebookAuthProvider.credential(accessToken))
35+
AuthCredential(FacebookAuthProvider.credential(accessToken))
2936
}
3037

3138
actual object GithubAuthProvider {
3239
actual fun credential(token: String): AuthCredential =
33-
AuthCredential(firebase.auth.GithubAuthProvider.credential(token))
40+
AuthCredential(GithubAuthProvider.credential(token))
3441
}
3542

3643
actual object GoogleAuthProvider {
3744
actual fun credential(idToken: String?, accessToken: String?): AuthCredential {
3845
require(idToken != null || accessToken != null) {
3946
"Both parameters are optional but at least one must be present."
4047
}
41-
return AuthCredential(firebase.auth.GoogleAuthProvider.credential(idToken, accessToken))
48+
return AuthCredential(GoogleAuthProvider.credential(idToken, accessToken))
4249
}
4350
}
4451

45-
actual class OAuthProvider(val js: firebase.auth.OAuthProvider) {
52+
actual class OAuthProvider(val js: JsOAuthProvider) {
4653

4754
actual constructor(
4855
provider: String,
4956
scopes: List<String>,
5057
customParameters: Map<String, String>,
5158
auth: FirebaseAuth
52-
) : this(firebase.auth.OAuthProvider(provider)) {
59+
) : this(JsOAuthProvider(provider)) {
5360
rethrow {
5461
scopes.forEach { js.addScope(it) }
5562
js.setCustomParameters(customParameters)
5663
}
5764
}
5865
actual companion object {
5966
actual fun credential(providerId: String, accessToken: String?, idToken: String?, rawNonce: String?): OAuthCredential = rethrow {
60-
firebase.auth.OAuthProvider(providerId)
67+
JsOAuthProvider(providerId)
6168
.credential(
6269
json(
6370
"accessToken" to (accessToken ?: undefined),
@@ -71,11 +78,11 @@ actual class OAuthProvider(val js: firebase.auth.OAuthProvider) {
7178
}
7279
}
7380

74-
actual class PhoneAuthProvider(val js: firebase.auth.PhoneAuthProvider) {
81+
actual class PhoneAuthProvider(val js: PhoneAuthProvider) {
7582

76-
actual constructor(auth: FirebaseAuth) : this(firebase.auth.PhoneAuthProvider(auth.js))
83+
actual constructor(auth: FirebaseAuth) : this(PhoneAuthProvider(auth.js))
7784

78-
actual fun credential(verificationId: String, smsCode: String): PhoneAuthCredential = PhoneAuthCredential(firebase.auth.PhoneAuthProvider.credential(verificationId, smsCode))
85+
actual fun credential(verificationId: String, smsCode: String): PhoneAuthCredential = PhoneAuthCredential(PhoneAuthProvider.credential(verificationId, smsCode))
7986
actual suspend fun verifyPhoneNumber(phoneNumber: String, verificationProvider: PhoneVerificationProvider): AuthCredential = rethrow {
8087
val verificationId = js.verifyPhoneNumber(phoneNumber, verificationProvider.verifier).await()
8188
val verificationCode = verificationProvider.getVerificationCode(verificationId)
@@ -84,10 +91,10 @@ actual class PhoneAuthProvider(val js: firebase.auth.PhoneAuthProvider) {
8491
}
8592

8693
actual interface PhoneVerificationProvider {
87-
val verifier: firebase.auth.ApplicationVerifier
94+
val verifier: ApplicationVerifier
8895
suspend fun getVerificationCode(verificationId: String): String
8996
}
9097

9198
actual object TwitterAuthProvider {
92-
actual fun credential(token: String, secret: String): AuthCredential = AuthCredential(firebase.auth.TwitterAuthProvider.credential(token, secret))
99+
actual fun credential(token: String, secret: String): AuthCredential = AuthCredential(TwitterAuthProvider.credential(token, secret))
93100
}

0 commit comments

Comments
 (0)