Skip to content

Commit f372c41

Browse files
committed
Raise firebase versions
1 parent 18711c1 commit f372c41

File tree

17 files changed

+420
-18
lines changed

17 files changed

+420
-18
lines changed

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ subprojects {
118118
"commonTestImplementation"("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
119119
if (this@afterEvaluate.name != "firebase-crashlytics") {
120120
"jvmMainApi"("dev.gitlive:firebase-java-sdk:0.1.1")
121-
"jvmMainApi"("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.0") {
121+
"jvmMainApi"("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutinesVersion") {
122122
exclude("com.google.android.gms")
123123
}
124124
"jsTestImplementation"(kotlin("test-js"))

firebase-app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ kotlin {
6969
}
7070
noPodspec()
7171
pod("FirebaseCore") {
72-
version = "10.9.0"
72+
version = "10.15.0"
7373
}
7474
}
7575
}

firebase-auth/build.gradle.kts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ kotlin {
7474
}
7575
noPodspec()
7676
pod("FirebaseAuth") {
77-
version = "10.9.0"
77+
version = "10.15.0"
7878
}
7979
}
8080
}
@@ -149,10 +149,6 @@ kotlin {
149149
}
150150
}
151151

152-
getByName("jvmMain") {
153-
kotlin.srcDir("src/androidMain/kotlin")
154-
}
155-
156152
if (supportIosTarget) {
157153
val iosMain by getting
158154
val iosSimulatorArm64Main by getting

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import platform.Foundation.*
1919
actual val Firebase.auth
2020
get() = FirebaseAuth(FIRAuth.auth())
2121

22+
@Suppress("CAST_NEVER_SUCCEEDS")
2223
actual fun Firebase.auth(app: FirebaseApp): FirebaseAuth = FirebaseAuth(
2324
FIRAuth.authWithApp(app.ios as objcnames.classes.FIRApp)
2425
)
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
@file:JvmName("android")
6+
package dev.gitlive.firebase.auth
7+
8+
import com.google.firebase.auth.ActionCodeEmailInfo
9+
import com.google.firebase.auth.ActionCodeMultiFactorInfo
10+
import com.google.firebase.auth.ActionCodeResult.*
11+
import com.google.firebase.auth.FirebaseAuth.AuthStateListener
12+
import dev.gitlive.firebase.Firebase
13+
import dev.gitlive.firebase.FirebaseApp
14+
import kotlinx.coroutines.channels.awaitClose
15+
import kotlinx.coroutines.flow.Flow
16+
import kotlinx.coroutines.flow.callbackFlow
17+
import kotlinx.coroutines.tasks.await
18+
19+
actual val Firebase.auth
20+
get() = FirebaseAuth(com.google.firebase.auth.FirebaseAuth.getInstance())
21+
22+
actual fun Firebase.auth(app: FirebaseApp) =
23+
FirebaseAuth(com.google.firebase.auth.FirebaseAuth.getInstance(app.android))
24+
25+
actual class FirebaseAuth internal constructor(val android: com.google.firebase.auth.FirebaseAuth) {
26+
actual val currentUser: FirebaseUser?
27+
get() = android.currentUser?.let { FirebaseUser(it) }
28+
29+
actual val authStateChanged: Flow<FirebaseUser?> get() = callbackFlow {
30+
val listener = object : AuthStateListener {
31+
override fun onAuthStateChanged(auth: com.google.firebase.auth.FirebaseAuth) {
32+
trySend(auth.currentUser?.let { FirebaseUser(it) })
33+
}
34+
}
35+
android.addAuthStateListener(listener)
36+
awaitClose { android.removeAuthStateListener(listener) }
37+
}
38+
39+
actual val idTokenChanged get(): Flow<FirebaseUser?> = callbackFlow {
40+
val listener = object : com.google.firebase.auth.FirebaseAuth.IdTokenListener {
41+
override fun onIdTokenChanged(auth: com.google.firebase.auth.FirebaseAuth) {
42+
trySend(auth.currentUser?.let { FirebaseUser(it) })
43+
}
44+
}
45+
android.addIdTokenListener(listener)
46+
awaitClose { android.removeIdTokenListener(listener) }
47+
}
48+
49+
actual var languageCode: String
50+
get() = android.languageCode.orEmpty()
51+
set(value) { android.setLanguageCode(value) }
52+
53+
54+
actual suspend fun applyActionCode(code: String) = android.applyActionCode(code).await().run { Unit }
55+
actual suspend fun confirmPasswordReset(code: String, newPassword: String) = android.confirmPasswordReset(code, newPassword).await().run { Unit }
56+
57+
actual suspend fun createUserWithEmailAndPassword(email: String, password: String) =
58+
AuthResult(android.createUserWithEmailAndPassword(email, password).await())
59+
60+
actual suspend fun fetchSignInMethodsForEmail(email: String): List<String> = android.fetchSignInMethodsForEmail(email).await().signInMethods.orEmpty()
61+
62+
actual suspend fun sendPasswordResetEmail(email: String, actionCodeSettings: ActionCodeSettings?) {
63+
android.sendPasswordResetEmail(email, actionCodeSettings?.toAndroid()).await()
64+
}
65+
66+
actual suspend fun sendSignInLinkToEmail(email: String, actionCodeSettings: ActionCodeSettings) = android.sendSignInLinkToEmail(email, actionCodeSettings.toAndroid()).await().run { Unit }
67+
68+
actual fun isSignInWithEmailLink(link: String) = android.isSignInWithEmailLink(link)
69+
70+
actual suspend fun signInWithEmailAndPassword(email: String, password: String) =
71+
AuthResult(android.signInWithEmailAndPassword(email, password).await())
72+
73+
actual suspend fun signInWithCustomToken(token: String) =
74+
AuthResult(android.signInWithCustomToken(token).await())
75+
76+
actual suspend fun signInAnonymously() = AuthResult(android.signInAnonymously().await())
77+
78+
actual suspend fun signInWithCredential(authCredential: AuthCredential) =
79+
AuthResult(android.signInWithCredential(authCredential.android).await())
80+
81+
actual suspend fun signInWithEmailLink(email: String, link: String) =
82+
AuthResult(android.signInWithEmailLink(email, link).await())
83+
84+
actual suspend fun signOut() = android.signOut()
85+
86+
actual suspend fun updateCurrentUser(user: FirebaseUser) = android.updateCurrentUser(user.android).await().run { Unit }
87+
actual suspend fun verifyPasswordResetCode(code: String): String = android.verifyPasswordResetCode(code).await()
88+
89+
actual suspend fun <T : ActionCodeResult> checkActionCode(code: String): T {
90+
val result = android.checkActionCode(code).await()
91+
@Suppress("UNCHECKED_CAST")
92+
return when(result.operation) {
93+
SIGN_IN_WITH_EMAIL_LINK -> ActionCodeResult.SignInWithEmailLink
94+
VERIFY_EMAIL -> ActionCodeResult.VerifyEmail(result.info!!.email)
95+
PASSWORD_RESET -> ActionCodeResult.PasswordReset(result.info!!.email)
96+
RECOVER_EMAIL -> (result.info as ActionCodeEmailInfo).run {
97+
ActionCodeResult.RecoverEmail(email, previousEmail)
98+
}
99+
VERIFY_BEFORE_CHANGE_EMAIL -> (result.info as ActionCodeEmailInfo).run {
100+
ActionCodeResult.VerifyBeforeChangeEmail(email, previousEmail)
101+
}
102+
REVERT_SECOND_FACTOR_ADDITION -> (result.info as ActionCodeMultiFactorInfo).run {
103+
ActionCodeResult.RevertSecondFactorAddition(email, MultiFactorInfo(multiFactorInfo))
104+
}
105+
ERROR -> throw UnsupportedOperationException(result.operation.toString())
106+
else -> throw UnsupportedOperationException(result.operation.toString())
107+
} as T
108+
}
109+
110+
actual fun useEmulator(host: String, port: Int) = android.useEmulator(host, port)
111+
}
112+
113+
actual class AuthResult internal constructor(val android: com.google.firebase.auth.AuthResult) {
114+
actual val user: FirebaseUser?
115+
get() = android.user?.let { FirebaseUser(it) }
116+
}
117+
118+
actual class AuthTokenResult(val android: com.google.firebase.auth.GetTokenResult) {
119+
// actual val authTimestamp: Long
120+
// get() = android.authTimestamp
121+
actual val claims: Map<String, Any>
122+
get() = android.claims
123+
// actual val expirationTimestamp: Long
124+
// get() = android.expirationTimestamp
125+
// actual val issuedAtTimestamp: Long
126+
// get() = android.issuedAtTimestamp
127+
actual val signInProvider: String?
128+
get() = android.signInProvider
129+
actual val token: String?
130+
get() = android.token
131+
}
132+
133+
internal fun ActionCodeSettings.toAndroid() = com.google.firebase.auth.ActionCodeSettings.newBuilder()
134+
.setUrl(url)
135+
.also { androidPackageName?.run { it.setAndroidPackageName(packageName, installIfNotAvailable, minimumVersion) } }
136+
.also { dynamicLinkDomain?.run { it.setDynamicLinkDomain(this) } }
137+
.setHandleCodeInApp(canHandleCodeInApp)
138+
.also { iOSBundleId?.run { it.setIOSBundleId(this) } }
139+
.build()
140+
141+
actual typealias FirebaseAuthException = com.google.firebase.auth.FirebaseAuthException
142+
actual typealias FirebaseAuthActionCodeException = com.google.firebase.auth.FirebaseAuthActionCodeException
143+
actual typealias FirebaseAuthEmailException = com.google.firebase.auth.FirebaseAuthEmailException
144+
actual typealias FirebaseAuthInvalidCredentialsException = com.google.firebase.auth.FirebaseAuthInvalidCredentialsException
145+
actual typealias FirebaseAuthWeakPasswordException = com.google.firebase.auth.FirebaseAuthWeakPasswordException
146+
actual typealias FirebaseAuthInvalidUserException = com.google.firebase.auth.FirebaseAuthInvalidUserException
147+
actual typealias FirebaseAuthMultiFactorException = com.google.firebase.auth.FirebaseAuthMultiFactorException
148+
actual typealias FirebaseAuthRecentLoginRequiredException = com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException
149+
actual typealias FirebaseAuthUserCollisionException = com.google.firebase.auth.FirebaseAuthUserCollisionException
150+
actual typealias FirebaseAuthWebException = com.google.firebase.auth.FirebaseAuthWebException
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.gitlive.firebase.auth
6+
7+
import android.app.Activity
8+
import com.google.firebase.FirebaseException
9+
import com.google.firebase.auth.OAuthProvider
10+
import com.google.firebase.auth.PhoneAuthProvider
11+
import kotlinx.coroutines.CompletableDeferred
12+
import kotlinx.coroutines.coroutineScope
13+
import kotlinx.coroutines.launch
14+
import kotlinx.coroutines.tasks.await
15+
import java.util.concurrent.TimeUnit
16+
17+
actual open class AuthCredential(open val android: com.google.firebase.auth.AuthCredential) {
18+
actual val providerId: String
19+
get() = android.provider
20+
}
21+
22+
actual class PhoneAuthCredential(override val android: com.google.firebase.auth.PhoneAuthCredential) : AuthCredential(android)
23+
24+
actual class OAuthCredential(override val android: com.google.firebase.auth.OAuthCredential) : AuthCredential(android)
25+
26+
actual object EmailAuthProvider {
27+
actual fun credential(
28+
email: String,
29+
password: String
30+
): AuthCredential = AuthCredential(com.google.firebase.auth.EmailAuthProvider.getCredential(email, password))
31+
32+
actual fun credentialWithLink(
33+
email: String,
34+
emailLink: String
35+
): AuthCredential = AuthCredential(com.google.firebase.auth.EmailAuthProvider.getCredentialWithLink(email, emailLink))
36+
}
37+
38+
actual object FacebookAuthProvider {
39+
actual fun credential(accessToken: String): AuthCredential = AuthCredential(com.google.firebase.auth.FacebookAuthProvider.getCredential(accessToken))
40+
}
41+
42+
actual object GithubAuthProvider {
43+
actual fun credential(token: String): AuthCredential = AuthCredential(com.google.firebase.auth.GithubAuthProvider.getCredential(token))
44+
}
45+
46+
actual object GoogleAuthProvider {
47+
actual fun credential(idToken: String?, accessToken: String?): AuthCredential {
48+
require(idToken != null || accessToken != null) {
49+
"Both parameters are optional but at least one must be present."
50+
}
51+
return AuthCredential(com.google.firebase.auth.GoogleAuthProvider.getCredential(idToken, accessToken))
52+
}
53+
}
54+
55+
actual class OAuthProvider(val android: com.google.firebase.auth.OAuthProvider) {
56+
57+
actual constructor(
58+
provider: String,
59+
scopes: List<String>,
60+
customParameters: Map<String, String>,
61+
auth: FirebaseAuth
62+
) : this(
63+
com.google.firebase.auth.OAuthProvider
64+
.newBuilder(provider, auth.android)
65+
.setScopes(scopes)
66+
.addCustomParameters(customParameters)
67+
.build()
68+
)
69+
70+
actual companion object {
71+
actual fun credential(providerId: String, accessToken: String?, idToken: String?, rawNonce: String?): OAuthCredential {
72+
val builder = OAuthProvider.newCredentialBuilder(providerId)
73+
accessToken?.let { builder.setAccessToken(it) }
74+
idToken?.let { builder.setIdToken(it) }
75+
rawNonce?.let { builder.setIdTokenWithRawNonce(idToken!!, it) }
76+
return OAuthCredential(builder.build() as com.google.firebase.auth.OAuthCredential)
77+
}
78+
}
79+
}
80+
81+
actual class PhoneAuthProvider(val android: com.google.firebase.auth.PhoneAuthProvider) {
82+
83+
actual constructor(auth: FirebaseAuth) : this(com.google.firebase.auth.PhoneAuthProvider.getInstance(auth.android))
84+
85+
actual fun credential(verificationId: String, smsCode: String): PhoneAuthCredential = PhoneAuthCredential(com.google.firebase.auth.PhoneAuthProvider.getCredential(verificationId, smsCode))
86+
87+
actual suspend fun verifyPhoneNumber(phoneNumber: String, verificationProvider: PhoneVerificationProvider): AuthCredential = coroutineScope {
88+
val response = CompletableDeferred<Result<AuthCredential>>()
89+
val callback = object :
90+
PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
91+
92+
override fun onCodeSent(verificationId: String, forceResending: PhoneAuthProvider.ForceResendingToken) {
93+
verificationProvider.codeSent {
94+
android.verifyPhoneNumber(phoneNumber, verificationProvider.timeout, verificationProvider.unit, verificationProvider.activity, this, forceResending)
95+
}
96+
}
97+
98+
override fun onCodeAutoRetrievalTimeOut(verificationId: String) {
99+
launch {
100+
val code = verificationProvider.getVerificationCode()
101+
try {
102+
response.complete(Result.success(credential(verificationId, code)))
103+
} catch (e: Exception) {
104+
response.complete(Result.failure(e))
105+
}
106+
}
107+
}
108+
109+
override fun onVerificationCompleted(credential: com.google.firebase.auth.PhoneAuthCredential) {
110+
response.complete(Result.success(AuthCredential(credential)))
111+
}
112+
113+
override fun onVerificationFailed(error: FirebaseException) {
114+
response.complete(Result.failure(error))
115+
}
116+
117+
}
118+
android.verifyPhoneNumber(phoneNumber, verificationProvider.timeout, verificationProvider.unit, verificationProvider.activity, callback)
119+
120+
response.await().getOrThrow()
121+
}
122+
}
123+
124+
actual interface PhoneVerificationProvider {
125+
val activity: Activity
126+
val timeout: Long
127+
val unit: TimeUnit
128+
fun codeSent(triggerResend: (Unit) -> Unit)
129+
suspend fun getVerificationCode(): String
130+
}
131+
132+
actual object TwitterAuthProvider {
133+
actual fun credential(token: String, secret: String): AuthCredential = AuthCredential(com.google.firebase.auth.TwitterAuthProvider.getCredential(token, secret))
134+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2020 GitLive Ltd. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package dev.gitlive.firebase.auth
6+
7+
import kotlinx.coroutines.tasks.await
8+
9+
actual class MultiFactor(val android: com.google.firebase.auth.MultiFactor) {
10+
actual val enrolledFactors: List<MultiFactorInfo>
11+
get() = android.enrolledFactors.map { MultiFactorInfo(it) }
12+
actual suspend fun enroll(multiFactorAssertion: MultiFactorAssertion, displayName: String?) = android.enroll(multiFactorAssertion.android, displayName).await().run { Unit }
13+
actual suspend fun getSession(): MultiFactorSession = MultiFactorSession(android.session.await())
14+
actual suspend fun unenroll(multiFactorInfo: MultiFactorInfo) = android.unenroll(multiFactorInfo.android).await().run { Unit }
15+
actual suspend fun unenroll(factorUid: String) = android.unenroll(factorUid).await().run { Unit }
16+
}
17+
18+
actual class MultiFactorInfo(val android: com.google.firebase.auth.MultiFactorInfo) {
19+
actual val displayName: String?
20+
get() = android.displayName
21+
actual val enrollmentTime: Double
22+
get() = android.enrollmentTimestamp.toDouble()
23+
actual val factorId: String
24+
get() = android.factorId
25+
actual val uid: String
26+
get() = android.uid
27+
}
28+
29+
actual class MultiFactorAssertion(val android: com.google.firebase.auth.MultiFactorAssertion) {
30+
actual val factorId: String
31+
get() = android.factorId
32+
}
33+
34+
actual class MultiFactorSession(val android: com.google.firebase.auth.MultiFactorSession)
35+
36+
actual class MultiFactorResolver(val android: com.google.firebase.auth.MultiFactorResolver) {
37+
actual val auth: FirebaseAuth = FirebaseAuth(android.firebaseAuth)
38+
actual val hints: List<MultiFactorInfo> = android.hints.map { MultiFactorInfo(it) }
39+
actual val session: MultiFactorSession = MultiFactorSession(android.session)
40+
41+
actual suspend fun resolveSignIn(assertion: MultiFactorAssertion): AuthResult = AuthResult(android.resolveSignIn(assertion.android).await())
42+
}

0 commit comments

Comments
 (0)