Skip to content

Commit beeab75

Browse files
authored
Merge branch 'master' into coroutine_cancellation_fix
2 parents 9b237c2 + e9d38a5 commit beeab75

File tree

22 files changed

+237
-447
lines changed

22 files changed

+237
-447
lines changed

.github/workflows/publish.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ jobs:
2424
arguments: :updateVersions
2525
- name: Grant execute permission for gradlew
2626
run: chmod +x gradlew
27-
- name: Install Homebrew
28-
run: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2927
- name: Install Carthage
3028
run: brew install carthage
3129
- name: Publish

.github/workflows/pull_request.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ jobs:
2020
java-version: 1.8
2121
- name: Grant execute permission for gradlew
2222
run: chmod +x gradlew
23-
- name: Install Homebrew
24-
run: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2523
- name: Install Carthage
2624
run: brew install carthage
2725
- name: Assemble

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ The following libraries are available for the various Firebase products.
1313

1414
| Service or Product | Gradle Dependency | API Coverage |
1515
| ------------------------------------------------------------------------------------ | :-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
16-
| [Authentication](https://firebase.google.com/docs/auth#kotlin-android) | [`dev.gitlive:firebase-auth:0.2.0`](https://search.maven.org/artifact/dev.gitlive/firebase-auth/0.2.0/pom) | [![40%](https://img.shields.io/badge/-50%25-red?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) |
17-
| [Realtime Database](https://firebase.google.com/docs/database#kotlin-android) | [`dev.gitlive:firebase-database:0.2.0`](https://search.maven.org/artifact/dev.gitlive/firebase-database/0.2.0/pom) | [![70%](https://img.shields.io/badge/-70%25-orange?style=flat-square)](/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/database.kt) |
18-
| [Cloud Firestore](https://firebase.google.com/docs/firestore#kotlin-android) | [`dev.gitlive:firebase-firestore:0.2.0`](https://search.maven.org/artifact/dev.gitlive/firebase-firestore/0.2.0/pom) | [![60%](https://img.shields.io/badge/-60%25-orange?style=flat-square)](/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt) |
19-
| [Cloud Functions](https://firebase.google.com/docs/functions/callable#kotlin-android)| [`dev.gitlive:firebase-functions:0.2.0`](https://search.maven.org/artifact/dev.gitlive/firebase-functions/0.2.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-functions/src/commonMain/kotlin/dev/gitlive/firebase/functions/functions.kt) |
20-
| [Cloud Messaging](https://firebase.google.com/docs/messaging#kotlin-android) | [`dev.gitlive:firebase-messaging:0.2.0`](https://search.maven.org/artifact/dev.gitlive/firebase-messaging/0.2.0/pom) | ![0%](https://img.shields.io/badge/-0%25-lightgrey?style=flat-square) |
21-
| [Cloud Storage](https://firebase.google.com/docs/storage#kotlin-android) | [`dev.gitlive:firebase-storage:0.2.0`](https://search.maven.org/artifact/dev.gitlive/firebase-storage/0.2.0/pom) | ![0%](https://img.shields.io/badge/-0%25-lightgrey?style=flat-square) |
16+
| [Authentication](https://firebase.google.com/docs/auth#kotlin-android) | [`dev.gitlive:firebase-auth:0.4.0`](https://search.maven.org/artifact/dev.gitlive/firebase-auth/0.4.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-auth/src/commonMain/kotlin/dev/gitlive/firebase/auth/auth.kt) |
17+
| [Realtime Database](https://firebase.google.com/docs/database#kotlin-android) | [`dev.gitlive:firebase-database:0.4.0`](https://search.maven.org/artifact/dev.gitlive/firebase-database/0.4.0/pom) | [![70%](https://img.shields.io/badge/-70%25-orange?style=flat-square)](/firebase-database/src/commonMain/kotlin/dev/gitlive/firebase/database/database.kt) |
18+
| [Cloud Firestore](https://firebase.google.com/docs/firestore#kotlin-android) | [`dev.gitlive:firebase-firestore:0.4.0`](https://search.maven.org/artifact/dev.gitlive/firebase-firestore/0.4.0/pom) | [![60%](https://img.shields.io/badge/-60%25-orange?style=flat-square)](/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt) |
19+
| [Cloud Functions](https://firebase.google.com/docs/functions/callable#kotlin-android)| [`dev.gitlive:firebase-functions:0.4.0`](https://search.maven.org/artifact/dev.gitlive/firebase-functions/0.4.0/pom) | [![80%](https://img.shields.io/badge/-80%25-green?style=flat-square)](/firebase-functions/src/commonMain/kotlin/dev/gitlive/firebase/functions/functions.kt) |
20+
| [Cloud Messaging](https://firebase.google.com/docs/messaging#kotlin-android) | [`dev.gitlive:firebase-messaging:0.4.0`](https://search.maven.org/artifact/dev.gitlive/firebase-messaging/0.4.0/pom) | ![0%](https://img.shields.io/badge/-0%25-lightgrey?style=flat-square) |
21+
| [Cloud Storage](https://firebase.google.com/docs/storage#kotlin-android) | [`dev.gitlive:firebase-storage:0.4.0`](https://search.maven.org/artifact/dev.gitlive/firebase-storage/0.4.0/pom) | ![0%](https://img.shields.io/badge/-0%25-lightgrey?style=flat-square) |
2222

2323
Is the Firebase library or API you need missing? [Create an issue](https://github.com/GitLiveApp/firebase-kotlin-sdk/issues/new?labels=API+coverage&template=increase-api-coverage.md&title=Add+%5Bclass+name%5D.%5Bfunction+name%5D+to+%5Blibrary+name%5D+for+%5Bplatform+names%5D) to request additional API coverage or be awesome and [submit a PR](https://github.com/GitLiveApp/firebase-kotlin-sdk/fork)
2424

@@ -138,12 +138,12 @@ If you are building a Kotlin multiplatform library which will be consumed from J
138138

139139
```json
140140
"dependencies": {
141-
"@gitlive/firebase-auth": "0.2.0",
142-
"@gitlive/firebase-database": "0.2.0",
143-
"@gitlive/firebase-firestore": "0.2.0",
144-
"@gitlive/firebase-functions": "0.2.0",
145-
"@gitlive/firebase-storage": "0.2.0",
146-
"@gitlive/firebase-messaging": "0.2.0"
141+
"@gitlive/firebase-auth": "0.4.0",
142+
"@gitlive/firebase-database": "0.4.0",
143+
"@gitlive/firebase-firestore": "0.4.0",
144+
"@gitlive/firebase-functions": "0.4.0",
145+
"@gitlive/firebase-storage": "0.4.0",
146+
"@gitlive/firebase-messaging": "0.4.0"
147147
}
148148
```
149149

build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ subprojects {
5656

5757

5858
tasks.withType<Sign>().configureEach {
59-
onlyIf { !project.gradle.startParameter.taskNames.contains("publishToMavenLocal")
60-
}
59+
onlyIf { !project.gradle.startParameter.taskNames.contains("publishToMavenLocal") }
6160
}
6261

6362

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

Lines changed: 33 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package dev.gitlive.firebase.auth
77

88
import com.google.firebase.auth.ActionCodeEmailInfo
99
import com.google.firebase.auth.ActionCodeMultiFactorInfo
10+
import com.google.firebase.auth.ActionCodeResult.*
1011
import com.google.firebase.auth.FirebaseAuth.AuthStateListener
1112
import dev.gitlive.firebase.Firebase
1213
import dev.gitlive.firebase.FirebaseApp
@@ -44,19 +45,18 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase.
4445
set(value) { android.setLanguageCode(value) }
4546

4647
actual suspend fun applyActionCode(code: String) = android.applyActionCode(code).await().run { Unit }
47-
actual suspend fun checkActionCode(code: String): ActionCodeResult = ActionCodeResult(android.checkActionCode(code).await())
4848
actual suspend fun confirmPasswordReset(code: String, newPassword: String) = android.confirmPasswordReset(code, newPassword).await().run { Unit }
4949

5050
actual suspend fun createUserWithEmailAndPassword(email: String, password: String) =
5151
AuthResult(android.createUserWithEmailAndPassword(email, password).await())
5252

53-
actual suspend fun fetchSignInMethodsForEmail(email: String): SignInMethodQueryResult = SignInMethodQueryResult(android.fetchSignInMethodsForEmail(email).await())
53+
actual suspend fun fetchSignInMethodsForEmail(email: String): List<String> = android.fetchSignInMethodsForEmail(email).await().signInMethods.orEmpty()
5454

5555
actual suspend fun sendPasswordResetEmail(email: String, actionCodeSettings: ActionCodeSettings?) {
56-
android.sendPasswordResetEmail(email, actionCodeSettings?.android).await()
56+
android.sendPasswordResetEmail(email, actionCodeSettings?.toAndroid()).await()
5757
}
5858

59-
actual suspend fun sendSignInLinkToEmail(email: String, actionCodeSettings: ActionCodeSettings) = android.sendSignInLinkToEmail(email, actionCodeSettings.android).await().run { Unit }
59+
actual suspend fun sendSignInLinkToEmail(email: String, actionCodeSettings: ActionCodeSettings) = android.sendSignInLinkToEmail(email, actionCodeSettings.toAndroid()).await().run { Unit }
6060

6161
actual suspend fun signInWithEmailAndPassword(email: String, password: String) =
6262
AuthResult(android.signInWithEmailAndPassword(email, password).await())
@@ -73,75 +73,42 @@ actual class FirebaseAuth internal constructor(val android: com.google.firebase.
7373

7474
actual suspend fun updateCurrentUser(user: FirebaseUser) = android.updateCurrentUser(user.android).await().run { Unit }
7575
actual suspend fun verifyPasswordResetCode(code: String): String = android.verifyPasswordResetCode(code).await()
76+
77+
actual suspend fun <T : ActionCodeResult> checkActionCode(code: String): T {
78+
val result = android.checkActionCode(code).await()
79+
@Suppress("UNCHECKED_CAST")
80+
return when(result.operation) {
81+
ERROR -> ActionCodeResult.Error
82+
SIGN_IN_WITH_EMAIL_LINK -> ActionCodeResult.SignInWithEmailLink
83+
VERIFY_EMAIL -> ActionCodeResult.VerifyEmail(result.info!!.email)
84+
PASSWORD_RESET -> ActionCodeResult.PasswordReset(result.info!!.email)
85+
RECOVER_EMAIL -> (result.info as ActionCodeEmailInfo).run {
86+
ActionCodeResult.RecoverEmail(email, previousEmail)
87+
}
88+
VERIFY_BEFORE_CHANGE_EMAIL -> (result.info as ActionCodeEmailInfo).run {
89+
ActionCodeResult.VerifyBeforeChangeEmail(email, previousEmail)
90+
}
91+
REVERT_SECOND_FACTOR_ADDITION -> (result.info as ActionCodeMultiFactorInfo).run {
92+
ActionCodeResult.RevertSecondFactorAddition(email, MultiFactorInfo(multiFactorInfo))
93+
}
94+
else -> throw UnsupportedOperationException(result.operation.toString())
95+
} as T
96+
}
97+
7698
}
7799

78100
actual class AuthResult internal constructor(val android: com.google.firebase.auth.AuthResult) {
79101
actual val user: FirebaseUser?
80102
get() = android.user?.let { FirebaseUser(it) }
81103
}
82104

83-
actual class ActionCodeResult(val android: com.google.firebase.auth.ActionCodeResult) {
84-
actual val operation: Operation
85-
get() = when (android.operation) {
86-
com.google.firebase.auth.ActionCodeResult.PASSWORD_RESET -> Operation.PasswordReset(this)
87-
com.google.firebase.auth.ActionCodeResult.VERIFY_EMAIL -> Operation.VerifyEmail(this)
88-
com.google.firebase.auth.ActionCodeResult.RECOVER_EMAIL -> Operation.RecoverEmail(this)
89-
com.google.firebase.auth.ActionCodeResult.ERROR -> Operation.Error
90-
com.google.firebase.auth.ActionCodeResult.SIGN_IN_WITH_EMAIL_LINK -> Operation.SignInWithEmailLink
91-
com.google.firebase.auth.ActionCodeResult.VERIFY_BEFORE_CHANGE_EMAIL -> Operation.VerifyBeforeChangeEmail(this)
92-
com.google.firebase.auth.ActionCodeResult.REVERT_SECOND_FACTOR_ADDITION -> Operation.RevertSecondFactorAddition(this)
93-
else -> Operation.Error
94-
}
95-
}
96-
97-
internal actual sealed class ActionCodeDataType<out T> {
98-
99-
actual abstract fun dataForResult(result: ActionCodeResult): T
100-
101-
actual object Email : ActionCodeDataType<String>() {
102-
override fun dataForResult(result: ActionCodeResult): String = result.android.info!!.email
103-
}
104-
actual object PreviousEmail : ActionCodeDataType<String>() {
105-
override fun dataForResult(result: ActionCodeResult): String = (result.android.info as ActionCodeEmailInfo).previousEmail
106-
}
107-
actual object MultiFactor : ActionCodeDataType<MultiFactorInfo?>() {
108-
override fun dataForResult(result: ActionCodeResult): MultiFactorInfo? = (result.android.info as? ActionCodeMultiFactorInfo)?.multiFactorInfo?.let { MultiFactorInfo(it) }
109-
}
110-
}
111-
112-
actual class SignInMethodQueryResult(val android: com.google.firebase.auth.SignInMethodQueryResult) {
113-
actual val signInMethods: List<String>
114-
get() = android.signInMethods ?: emptyList()
115-
}
116-
117-
actual class ActionCodeSettings private constructor(val android: com.google.firebase.auth.ActionCodeSettings) {
118-
119-
actual constructor(url: String,
120-
androidPackageName: AndroidPackageName?,
121-
dynamicLinkDomain: String?,
122-
canHandleCodeInApp: Boolean,
123-
iOSBundleId: String?
124-
) : this(com.google.firebase.auth.ActionCodeSettings.newBuilder().apply {
125-
this.url = url
126-
androidPackageName?.let {
127-
this.setAndroidPackageName(it.androidPackageName, it.installIfNotAvailable, it.minimumVersion)
128-
}
129-
this.dynamicLinkDomain = dynamicLinkDomain
130-
this.handleCodeInApp = canHandleCodeInApp
131-
this.iosBundleId = iosBundleId
132-
}.build())
133-
134-
actual val canHandleCodeInApp: Boolean
135-
get() = android.canHandleCodeInApp()
136-
actual val androidPackageName: AndroidPackageName?
137-
get() = android.androidPackageName?.let {
138-
AndroidPackageName(it, android.androidInstallApp, android.androidMinimumVersion)
139-
}
140-
actual val iOSBundle: String?
141-
get() = android.iosBundle
142-
actual val url: String
143-
get() = android.url
144-
}
105+
internal fun ActionCodeSettings.toAndroid() = com.google.firebase.auth.ActionCodeSettings.newBuilder()
106+
.setUrl(url)
107+
.also { androidPackageName?.run { it.setAndroidPackageName(packageName, installIfNotAvailable, minimumVersion) } }
108+
.also { dynamicLinkDomain?.run { it.setDynamicLinkDomain(this) } }
109+
.setHandleCodeInApp(canHandleCodeInApp)
110+
.also { iOSBundleId?.run { it.setIOSBundleId(this) } }
111+
.build()
145112

146113
actual typealias FirebaseAuthException = com.google.firebase.auth.FirebaseAuthException
147114
actual typealias FirebaseAuthActionCodeException = com.google.firebase.auth.FirebaseAuthActionCodeException

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

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package dev.gitlive.firebase.auth
66

77
import android.app.Activity
88
import com.google.firebase.FirebaseException
9+
import com.google.firebase.auth.OAuthProvider
910
import com.google.firebase.auth.PhoneAuthProvider
1011
import kotlinx.coroutines.CompletableDeferred
1112
import kotlinx.coroutines.coroutineScope
@@ -45,24 +46,12 @@ actual class OAuthProvider(val android: com.google.firebase.auth.OAuthProvider.B
4546
actual constructor(provider: String, auth: FirebaseAuth) : this(com.google.firebase.auth.OAuthProvider.newBuilder(provider, auth.android), auth)
4647

4748
actual companion object {
48-
actual fun credentials(type: OAuthCredentialsType): AuthCredential {
49-
val credential = com.google.firebase.auth.OAuthProvider.newCredentialBuilder(type.providerId).apply {
50-
when (type) {
51-
is OAuthCredentialsType.AccessToken -> accessToken = type.accessToken
52-
is OAuthCredentialsType.IdAndAccessToken -> {
53-
accessToken = type.accessToken
54-
setIdToken(type.idToken)
55-
}
56-
is OAuthCredentialsType.IdAndAccessTokenAndRawNonce -> {
57-
accessToken = type.accessToken
58-
setIdTokenWithRawNonce(type.idToken, type.rawNonce)
59-
}
60-
is OAuthCredentialsType.IdTokenAndRawNonce -> {
61-
setIdTokenWithRawNonce(type.idToken, type.rawNonce)
62-
}
63-
}
64-
}.build()
65-
return (credential as? com.google.firebase.auth.OAuthCredential)?.let { OAuthCredential(it) } ?: AuthCredential(credential)
49+
actual fun credential(providerId: String, accessToken: String?, idToken: String?, rawNonce: String?): OAuthCredential {
50+
val builder = OAuthProvider.newCredentialBuilder(providerId)
51+
accessToken?.let { builder.accessToken = it }
52+
idToken?.let { builder.idToken = it }
53+
rawNonce?.let { builder.setIdTokenWithRawNonce(idToken!!, it) }
54+
return OAuthCredential(builder.build() as com.google.firebase.auth.OAuthCredential)
6655
}
6756
}
6857

@@ -99,9 +88,7 @@ actual class PhoneAuthProvider(val android: com.google.firebase.auth.PhoneAuthPr
9988
launch {
10089
val code = verificationProvider.getVerificationCode()
10190
try {
102-
val credentials =
103-
credential(verificationId, code)
104-
response.complete(Result.success(credentials))
91+
response.complete(Result.success(credential(verificationId, code)))
10592
} catch (e: Exception) {
10693
response.complete(Result.failure(e))
10794
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ actual class FirebaseUser internal constructor(val android: com.google.firebase.
3838
actual suspend fun reauthenticate(credential: AuthCredential) = android.reauthenticate(credential.android).await().run { Unit }
3939
actual suspend fun reauthenticateAndRetrieveData(credential: AuthCredential): AuthResult = AuthResult(android.reauthenticateAndRetrieveData(credential.android).await())
4040
actual suspend fun sendEmailVerification(actionCodeSettings: ActionCodeSettings?) {
41-
val request = actionCodeSettings?.android?.let { android.sendEmailVerification(it) } ?: android.sendEmailVerification()
42-
request.await().run { Unit }
41+
val request = actionCodeSettings?.let { android.sendEmailVerification(it.toAndroid()) } ?: android.sendEmailVerification()
42+
request.await()
4343
}
4444
actual suspend fun unlink(provider: String): FirebaseUser? = android.unlink(provider).await().user?.let { FirebaseUser(it) }
4545
actual suspend fun updateEmail(email: String) = android.updateEmail(email).await().run { Unit }
@@ -52,7 +52,8 @@ actual class FirebaseUser internal constructor(val android: com.google.firebase.
5252
}.build()
5353
android.updateProfile(request).await()
5454
}
55-
actual suspend fun verifyBeforeUpdateEmail(newEmail: String, actionCodeSettings: ActionCodeSettings?) = android.verifyBeforeUpdateEmail(newEmail, actionCodeSettings?.android).await().run { Unit }
55+
actual suspend fun verifyBeforeUpdateEmail(newEmail: String, actionCodeSettings: ActionCodeSettings?) =
56+
android.verifyBeforeUpdateEmail(newEmail, actionCodeSettings?.toAndroid()).await().run { Unit }
5657
}
5758

5859
actual class UserInfo(val android: com.google.firebase.auth.UserInfo) {

0 commit comments

Comments
 (0)