Skip to content

Commit 2a673e4

Browse files
authored
Add useEmulator() API (#123)
* Add using emulator for firebase-auth * Try test actions with emulator * Fix emulator project ID * Update .gitignore * Implement Firestore useEmulator() API * Implement Realtime Database useEmulator() API * Deprecate useFunctionsEmulator() * Revert GitHub Actions config * Remove unnecessary XML config * Cleanup * Move test firebase configs to 'test' dir * Use Android's clear text traffic config for test target only * Fix "TypeError: e.log is not a function" error * Map "auth/email-already-in-use" JS error code to FirebaseAuthUserCollisionException
1 parent 061ef51 commit 2a673e4

File tree

34 files changed

+165
-31
lines changed

34 files changed

+165
-31
lines changed

.github/workflows/pull_request.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ jobs:
2222
run: chmod +x gradlew
2323
- name: Install Carthage
2424
run: brew list carthage || brew install carthage
25+
- name: Install Firebase tools
26+
run: npm install -g firebase-tools
27+
- name: Start Firebase emulator
28+
run: "firebase emulators:start --config=./test/firebase.json &"
2529
- name: Assemble
2630
run: ./gradlew assemble
2731
- name: Run JS Tests

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ firebase-database/src/iosMain/c_interop/modules/
1313
Firebase*.zip
1414
/Firebase
1515
/.DS_Store
16+
*.log
1617

1718

1819
/**/Cartfile.resolved

firebase-auth/build.gradle.kts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ android {
3131
getByName("main") {
3232
manifest.srcFile("src/androidMain/AndroidManifest.xml")
3333
}
34-
getByName("androidTest").java.srcDir(file("src/androidAndroidTest/kotlin"))
34+
getByName("androidTest"){
35+
java.srcDir(file("src/androidAndroidTest/kotlin"))
36+
manifest.srcFile("src/androidAndroidTest/AndroidManifest.xml")
37+
}
3538
}
3639
testOptions {
3740
unitTests.apply {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2+
package="dev.gitlive.firebase.auth">
3+
4+
<application android:usesCleartextTraffic="true" />
5+
</manifest>

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ package dev.gitlive.firebase.auth
88
import androidx.test.platform.app.InstrumentationRegistry
99
import kotlinx.coroutines.runBlocking
1010

11+
actual val emulatorHost: String = "10.0.2.2"
12+
1113
actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext
1214

13-
actual fun runTest(test: suspend () -> Unit) = runBlocking { test() }
15+
actual fun runTest(test: suspend () -> Unit) = runBlocking { test() }

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase.
5151
get() = android.languageCode ?: ""
5252
set(value) { android.setLanguageCode(value) }
5353

54+
5455
actual suspend fun applyActionCode(code: String) = android.applyActionCode(code).await().run { Unit }
5556
actual suspend fun confirmPasswordReset(code: String, newPassword: String) = android.confirmPasswordReset(code, newPassword).await().run { Unit }
5657

@@ -102,6 +103,7 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase.
102103
} as T
103104
}
104105

106+
actual fun useEmulator(host: String, port: Int) = android.useEmulator(host, port)
105107
}
106108

107109
actual class AuthResult internal constructor(val android: com.google.firebase.auth.AuthResult) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ expect class FirebaseAuth {
3434
suspend fun signOut()
3535
suspend fun updateCurrentUser(user: FirebaseUser)
3636
suspend fun verifyPasswordResetCode(code: String): String
37+
fun useEmulator(host: String, port: Int)
3738
}
3839

3940
expect class AuthResult {

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

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import dev.gitlive.firebase.*
88
import kotlin.random.Random
99
import kotlin.test.*
1010

11+
expect val emulatorHost: String
1112
expect val context: Any
1213
expect fun runTest(test: suspend () -> Unit)
1314

@@ -17,22 +18,26 @@ class FirebaseAuthTest {
1718
fun initializeFirebase() {
1819
Firebase
1920
.takeIf { Firebase.apps(context).isEmpty() }
20-
?.initialize(
21-
context,
22-
FirebaseOptions(
23-
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
24-
apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0",
25-
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
26-
storageBucket = "fir-kotlin-sdk.appspot.com",
27-
projectId = "fir-kotlin-sdk"
21+
?.apply {
22+
initialize(
23+
context,
24+
FirebaseOptions(
25+
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
26+
apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0",
27+
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
28+
storageBucket = "fir-kotlin-sdk.appspot.com",
29+
projectId = "fir-kotlin-sdk"
30+
)
2831
)
29-
)
32+
Firebase.auth.useEmulator(emulatorHost, 9099)
33+
}
3034
}
3135

3236
@Test
3337
fun testSignInWithUsernameAndPassword() = runTest {
38+
val uid = getTestUid("[email protected]", "test123")
3439
val result = Firebase.auth.signInWithEmailAndPassword("[email protected]", "test123")
35-
assertEquals("mn8kgIFnxLO7il8GpTa5g0ObP6I2", result.user!!.uid)
40+
assertEquals(uid, result.user!!.uid)
3641
}
3742

3843
@Test
@@ -85,9 +90,27 @@ class FirebaseAuthTest {
8590

8691
@Test
8792
fun testSignInWithCredential() = runTest {
93+
val uid = getTestUid("[email protected]", "test123")
8894
val credential = EmailAuthProvider.credential("[email protected]", "test123")
8995
val result = Firebase.auth.signInWithCredential(credential)
90-
assertEquals("mn8kgIFnxLO7il8GpTa5g0ObP6I2", result.user!!.uid)
96+
assertEquals(uid, result.user!!.uid)
97+
}
9198

99+
private suspend fun getTestUid(email: String, password: String): String {
100+
val uid = Firebase.auth.let {
101+
val user = try {
102+
it.createUserWithEmailAndPassword(email, password).user
103+
} catch (e: FirebaseAuthUserCollisionException) {
104+
// the user already exists, just sign in for getting user's ID
105+
it.signInWithEmailAndPassword(email, password).user
106+
}
107+
user!!.uid
108+
}
109+
110+
check(Firebase.auth.currentUser != null)
111+
Firebase.auth.signOut()
112+
check(Firebase.auth.currentUser == null)
113+
114+
return uid
92115
}
93-
}
116+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ actual class FirebaseAuth internal constructor(val ios: FIRAuth) {
8989
else -> throw UnsupportedOperationException(result.operation.toString())
9090
} as T
9191
}
92+
93+
actual fun useEmulator(host: String, port: Int) = ios.useEmulatorWithHost(host, port.toLong())
9294
}
9395

9496
actual class AuthResult internal constructor(val ios: FIRAuthDataResult) {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package dev.gitlive.firebase.auth
77
import kotlinx.coroutines.*
88
import platform.Foundation.*
99

10+
actual val emulatorHost: String = "localhost"
11+
1012
actual val context: Any = Unit
1113

1214
actual fun runTest(test: suspend () -> Unit) = runBlocking {
@@ -19,4 +21,4 @@ actual fun runTest(test: suspend () -> Unit) = runBlocking {
1921
yield()
2022
}
2123
testRun.await()
22-
}
24+
}

0 commit comments

Comments
 (0)