Skip to content

Commit 4abbcd7

Browse files
mksmdvdffnbransby
andauthored
Sign in with credential implementation (#63)
* Sign in with credential implementation * js fix * minor changes * Replace internal constructors with public * Credentials tests * Add EmailAuthProvider * Review fixes Co-authored-by: Nicholas Bransby-Williams <[email protected]>
1 parent 67ebe0d commit 4abbcd7

File tree

10 files changed

+76
-13
lines changed
  • firebase-auth
    • src
      • androidAndroidTest/kotlin/dev/gitlive/firebase/auth
      • androidMain/kotlin/dev/gitlive/firebase/auth
      • commonMain/kotlin/dev/gitlive/firebase/auth
      • commonTest/kotlin/dev/gitlive/firebase/auth
      • iosMain/kotlin/dev/gitlive/firebase/auth
      • iosTest/kotlin/dev/gitlive/firebase/auth
      • jsMain/kotlin/dev/gitlive/firebase/auth
      • jsTest/kotlin/dev/gitlive/firebase/auth
  • firebase-common/src/jsMain/kotlin/dev/gitlive/firebase

10 files changed

+76
-13
lines changed

firebase-auth/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ kotlin {
100100
implementation(project(":firebase-common"))
101101
}
102102
}
103+
103104
val androidMain by getting {
104105
dependencies {
105106
api("com.google.firebase:firebase-auth:19.1.0")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ import kotlinx.coroutines.runBlocking
1010

1111
actual val context: Any = InstrumentationRegistry.getInstrumentation().targetContext
1212

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

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package dev.gitlive.firebase.auth
66

7+
import com.google.firebase.auth.EmailAuthProvider
78
import com.google.firebase.auth.FirebaseAuth.AuthStateListener
89
import dev.gitlive.firebase.Firebase
910
import dev.gitlive.firebase.FirebaseApp
@@ -45,10 +46,14 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase.
4546
android.addAuthStateListener(listener)
4647
awaitClose { android.removeAuthStateListener(listener) }
4748
}
49+
actual suspend fun signInWithCredential(authCredential: AuthCredential) =
50+
AuthResult(android.signInWithCredential(authCredential.android).await())
4851

4952
actual suspend fun signOut() = android.signOut()
5053
}
5154

55+
actual class AuthCredential(val android: com.google.firebase.auth.AuthCredential)
56+
5257
actual class AuthResult internal constructor(val android: com.google.firebase.auth.AuthResult) {
5358
actual val user: FirebaseUser?
5459
get() = android.user?.let { FirebaseUser(it) }
@@ -79,3 +84,9 @@ actual typealias FirebaseAuthRecentLoginRequiredException = com.google.firebase.
7984
actual typealias FirebaseAuthUserCollisionException = com.google.firebase.auth.FirebaseAuthUserCollisionException
8085
actual typealias FirebaseAuthWebException = com.google.firebase.auth.FirebaseAuthWebException
8186

87+
actual object EmailAuthProvider {
88+
actual fun credentialWithEmail(
89+
email: String,
90+
password: String
91+
): AuthCredential = AuthCredential(EmailAuthProvider.getCredential(email, password))
92+
}

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
@file:Suppress("EXTENSION_SHADOWED_BY_MEMBER")
6+
67
package dev.gitlive.firebase.auth
78

89
import dev.gitlive.firebase.Firebase
@@ -22,6 +23,7 @@ expect class FirebaseAuth {
2223
suspend fun createUserWithEmailAndPassword(email: String, password: String): AuthResult
2324
suspend fun signInWithCustomToken(token: String): AuthResult
2425
suspend fun signInAnonymously(): AuthResult
26+
suspend fun signInWithCredential(authCredential: AuthCredential): AuthResult
2527
suspend fun signOut()
2628
}
2729

@@ -40,12 +42,18 @@ expect class FirebaseUser {
4042
suspend fun sendEmailVerification()
4143
}
4244

43-
expect open class FirebaseAuthException: FirebaseException
44-
expect class FirebaseAuthActionCodeException: FirebaseAuthException
45-
expect class FirebaseAuthEmailException: FirebaseAuthException
46-
expect class FirebaseAuthInvalidCredentialsException: FirebaseAuthException
47-
expect class FirebaseAuthInvalidUserException: FirebaseAuthException
48-
expect class FirebaseAuthRecentLoginRequiredException: FirebaseAuthException
49-
expect class FirebaseAuthUserCollisionException: FirebaseAuthException
50-
expect class FirebaseAuthWebException: FirebaseAuthException
45+
expect open class FirebaseAuthException : FirebaseException
46+
expect class FirebaseAuthActionCodeException : FirebaseAuthException
47+
expect class FirebaseAuthEmailException : FirebaseAuthException
48+
expect class FirebaseAuthInvalidCredentialsException : FirebaseAuthException
49+
expect class FirebaseAuthInvalidUserException : FirebaseAuthException
50+
expect class FirebaseAuthRecentLoginRequiredException : FirebaseAuthException
51+
expect class FirebaseAuthUserCollisionException : FirebaseAuthException
52+
expect class FirebaseAuthWebException : FirebaseAuthException
53+
54+
expect class AuthCredential
55+
56+
expect object EmailAuthProvider{
57+
fun credentialWithEmail(email: String, password: String): AuthCredential
58+
}
5159

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class FirebaseAuthTest {
2626
storageBucket = "fir-kotlin-sdk.appspot.com",
2727
projectId = "fir-kotlin-sdk"
2828
)
29-
)
29+
)
3030
}
3131

3232
@Test
@@ -70,4 +70,12 @@ class FirebaseAuthTest {
7070

7171
createResult.user!!.delete()
7272
}
73-
}
73+
74+
@Test
75+
fun testSignInWithCredential() = runTest {
76+
val credential = EmailAuthProvider.credentialWithEmail("[email protected]", "test123")
77+
val result = Firebase.auth.signInWithCredential(credential)
78+
assertEquals("mn8kgIFnxLO7il8GpTa5g0ObP6I2", result.user!!.uid)
79+
80+
}
81+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ actual class FirebaseAuth internal constructor(val ios: FIRAuth) {
4242
actual suspend fun signInAnonymously() =
4343
AuthResult(ios.awaitResult { signInAnonymouslyWithCompletion(it) })
4444

45+
actual suspend fun signInWithCredential(authCredential: AuthCredential) =
46+
AuthResult(ios.awaitResult { signInWithCredential(authCredential.ios, it) })
47+
4548
actual suspend fun signOut() = ios.throwError { signOut(it) }.run { Unit }
4649

4750
actual val authStateChanged get() = callbackFlow {
@@ -80,6 +83,16 @@ actual open class FirebaseAuthRecentLoginRequiredException(message: String): Fir
8083
actual open class FirebaseAuthUserCollisionException(message: String): FirebaseAuthException(message)
8184
actual open class FirebaseAuthWebException(message: String): FirebaseAuthException(message)
8285

86+
actual class AuthCredential(val ios: FIRAuthCredential)
87+
88+
actual object EmailAuthProvider {
89+
actual fun credentialWithEmail(
90+
email: String,
91+
password: String
92+
): AuthCredential =
93+
AuthCredential(FIREmailAuthProvider.credentialWithEmail(email = email, password = password))
94+
}
95+
8396

8497
private fun <T, R> T.throwError(block: T.(errorPointer: CPointer<ObjCObjectVar<NSError?>>) -> R): R {
8598
memScoped {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ actual fun runTest(test: suspend () -> Unit) = runBlocking {
1919
yield()
2020
}
2121
testRun.await()
22-
}
22+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,13 @@ actual class FirebaseAuth internal constructor(val js: firebase.auth.Auth) {
4343
}
4444
awaitClose { unsubscribe() }
4545
}
46+
47+
actual suspend fun signInWithCredential(authCredential: AuthCredential) =
48+
rethrow { AuthResult(js.signInWithCredential(authCredential.js).await()) }
4649
}
4750

51+
actual class AuthCredential(val js: firebase.auth.AuthCredential)
52+
4853
actual class AuthResult internal constructor(val js: firebase.auth.AuthResult) {
4954
actual val user: FirebaseUser?
5055
get() = rethrow { js.user?.let { FirebaseUser(it) } }
@@ -103,3 +108,10 @@ private fun errorToException(cause: Throwable) = when(val code = cause.asDynamic
103108
// "auth/unauthorized-domain" ->
104109
else -> FirebaseAuthException(code, cause)
105110
}
111+
112+
actual object EmailAuthProvider {
113+
actual fun credentialWithEmail(
114+
email: String,
115+
password: String
116+
): AuthCredential = AuthCredential(firebase.auth.EmailAuthProvider.credential(email, password))
117+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ import kotlinx.coroutines.promise
99

1010
actual val context: Any = Unit
1111

12-
actual fun runTest(test: suspend () -> Unit) = GlobalScope.promise { test() }.unsafeCast<Unit>()
12+
actual fun runTest(test: suspend () -> Unit) = GlobalScope.promise { test() }.unsafeCast<Unit>()

firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/externals.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,23 @@ external object firebase {
6262
fun createUserWithEmailAndPassword(email: String, password: String): Promise<AuthResult>
6363
fun signInWithCustomToken(token: String): Promise<AuthResult>
6464
fun signInAnonymously(): Promise<AuthResult>
65+
fun signInWithCredential(authCredential: AuthCredential): Promise<AuthResult>
6566
fun signOut(): Promise<Unit>
6667

6768
fun onAuthStateChanged(nextOrObserver: (user.User?) -> Unit): () -> Unit
6869
}
6970
interface AuthResult {
7071
val user: user.User?
7172
}
73+
74+
interface AuthCredential
75+
76+
abstract class EmailAuthProvider {
77+
companion object {
78+
fun credential(email : String, password : String) : AuthCredential
79+
}
80+
}
81+
7282
}
7383

7484
fun User(a: Any,b: Any,c: Any): user.User

0 commit comments

Comments
 (0)