Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ buildscript {

val compileSdkVersion by extra(34)
val targetSdkVersion by extra(34)
val minSdkVersion by extra(21)
val minSdkVersion by extra(23)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Required By Android FB 34+


tasks {
register("updateVersions") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import dev.gitlive.firebase.FirebaseOptions
import dev.gitlive.firebase.apps
import dev.gitlive.firebase.initialize
import dev.gitlive.firebase.runBlockingTest
import kotlin.random.Random
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand All @@ -27,7 +28,7 @@ class FirebaseAnalyticsTest {
val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize(
context,
FirebaseOptions(
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
applicationId = "1:${Random.nextInt()}:ios:dd1f6688bad7af768c841a",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Android, the HeartBeatInfoStorage somewhat annoyingly does not clear properly between tests. Since it uses the applicationId as a persistenceKey and this ID doesnt really matter in tests, the easiest solution is to just randomize it

apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0",
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
storageBucket = "fir-kotlin-sdk.appspot.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public actual data class FirebaseApp internal constructor(internal val ios: FIRA
actual val name: String
get() = ios.name
actual val options: FirebaseOptions
get() = ios.options.run { FirebaseOptions(bundleID, APIKey!!, databaseURL!!, trackingID, storageBucket, projectID, GCMSenderID) }
get() = ios.options.run { FirebaseOptions(bundleID, APIKey!!, databaseURL!!, null, storageBucket, projectID, GCMSenderID) }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed on the iOS SDK


public actual suspend fun delete() {
val deleted = CompletableDeferred<Unit>()
Expand All @@ -46,7 +46,6 @@ public actual fun Firebase.apps(context: Any?): List<FirebaseApp> = FIRApp.allAp
private fun FirebaseOptions.toIos() = FIROptions(this@toIos.applicationId, this@toIos.gcmSenderId ?: "").apply {
APIKey = this@toIos.apiKey
databaseURL = this@toIos.databaseUrl
trackingID = this@toIos.gaTrackingId
storageBucket = this@toIos.storageBucket
projectID = this@toIos.projectId
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.gitlive.firebase

import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals

Expand All @@ -13,7 +14,7 @@ class FirebaseAppTest {
Firebase.initialize(
context,
FirebaseOptions(
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
applicationId = "1:${Random.nextInt()}:ios:dd1f6688bad7af768c841a",
apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0",
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
storageBucket = "fir-kotlin-sdk.appspot.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,25 @@ public actual class FirebaseAuth internal constructor(internal val android: com.
@Suppress("UNCHECKED_CAST")
return when (result.operation) {
SIGN_IN_WITH_EMAIL_LINK -> ActionCodeResult.SignInWithEmailLink

VERIFY_EMAIL -> ActionCodeResult.VerifyEmail(result.info!!.email)

PASSWORD_RESET -> ActionCodeResult.PasswordReset(result.info!!.email)

RECOVER_EMAIL -> (result.info as ActionCodeEmailInfo).run {
ActionCodeResult.RecoverEmail(email, previousEmail)
}

VERIFY_BEFORE_CHANGE_EMAIL -> (result.info as ActionCodeEmailInfo).run {
ActionCodeResult.VerifyBeforeChangeEmail(email, previousEmail)
}

REVERT_SECOND_FACTOR_ADDITION -> (result.info as ActionCodeMultiFactorInfo).run {
ActionCodeResult.RevertSecondFactorAddition(email, MultiFactorInfo(multiFactorInfo))
}

ERROR -> throw UnsupportedOperationException(result.operation.toString())

else -> throw UnsupportedOperationException(result.operation.toString())
} as T
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ public actual class AuthTokenResult(internal val ios: FIRAuthTokenResult) {
internal fun ActionCodeSettings.toIos() = FIRActionCodeSettings().also {
it.setURL(NSURL.URLWithString(url))
androidPackageName?.run { it.setAndroidPackageName(packageName, installIfNotAvailable, minimumVersion) }
it.setDynamicLinkDomain(dynamicLinkDomain)
it.setLinkDomain(linkDomain)
it.setHandleCodeInApp(canHandleCodeInApp)
iOSBundleId?.run { it.setIOSBundleID(this) }
Expand Down Expand Up @@ -266,5 +265,6 @@ private fun NSError.toException() = when (domain) {

else -> FirebaseAuthException(toString())
}

else -> FirebaseAuthException(toString())
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class FirebaseAuthTest {
val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize(
context,
FirebaseOptions(
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
applicationId = "1:${Random.nextInt()}:ios:dd1f6688bad7af768c841a",
apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0",
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
storageBucket = "fir-kotlin-sdk.appspot.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,23 @@ public actual class FirebaseAuth internal constructor(internal val js: Auth) {
@Suppress("UNCHECKED_CAST")
return when (result.operation) {
"EMAIL_SIGNIN" -> ActionCodeResult.SignInWithEmailLink

"VERIFY_EMAIL" -> ActionCodeResult.VerifyEmail(result.data.email!!)

"PASSWORD_RESET" -> ActionCodeResult.PasswordReset(result.data.email!!)

"RECOVER_EMAIL" -> ActionCodeResult.RecoverEmail(result.data.email!!, result.data.previousEmail!!)

"VERIFY_AND_CHANGE_EMAIL" -> ActionCodeResult.VerifyBeforeChangeEmail(
result.data.email!!,
result.data.previousEmail!!,
)

"REVERT_SECOND_FACTOR_ADDITION" -> ActionCodeResult.RevertSecondFactorAddition(
result.data.email!!,
result.data.multiFactorInfo?.let { MultiFactorInfo(it) },
)

else -> throw UnsupportedOperationException(result.operation)
} as T
}
Expand Down Expand Up @@ -208,26 +214,39 @@ private inline fun <R> rethrow(function: () -> R): R {

private fun errorToException(cause: dynamic) = when (val code = cause.code?.toString()?.lowercase()) {
"auth/invalid-user-token" -> FirebaseAuthInvalidUserException(code, cause.unsafeCast<Throwable>())

"auth/requires-recent-login" -> FirebaseAuthRecentLoginRequiredException(code, cause.unsafeCast<Throwable>())

"auth/user-disabled" -> FirebaseAuthInvalidUserException(code, cause.unsafeCast<Throwable>())

"auth/user-token-expired" -> FirebaseAuthInvalidUserException(code, cause.unsafeCast<Throwable>())

"auth/web-storage-unsupported" -> FirebaseAuthWebException(code, cause.unsafeCast<Throwable>())

"auth/network-request-failed" -> FirebaseNetworkException(code, cause.unsafeCast<Throwable>())

"auth/timeout" -> FirebaseNetworkException(code, cause.unsafeCast<Throwable>())

"auth/weak-password" -> FirebaseAuthWeakPasswordException(code, cause.unsafeCast<Throwable>())

"auth/invalid-credential",
"auth/invalid-verification-code",
"auth/missing-verification-code",
"auth/invalid-verification-id",
"auth/missing-verification-id",
-> FirebaseAuthInvalidCredentialsException(code, cause.unsafeCast<Throwable>())

"auth/maximum-second-factor-count-exceeded",
"auth/second-factor-already-in-use",
-> FirebaseAuthMultiFactorException(code, cause.unsafeCast<Throwable>())

"auth/credential-already-in-use" -> FirebaseAuthUserCollisionException(code, cause.unsafeCast<Throwable>())

"auth/email-already-in-use" -> FirebaseAuthUserCollisionException(code, cause.unsafeCast<Throwable>())

"auth/invalid-email" -> FirebaseAuthEmailException(code, cause.unsafeCast<Throwable>())
// "auth/app-deleted" ->

// "auth/app-deleted" ->
// "auth/app-not-authorized" ->
// "auth/argument-error" ->
// "auth/invalid-api-key" ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,25 @@ public actual class FirebaseAuth internal constructor(internal val android: com.
@Suppress("UNCHECKED_CAST")
return when (result.operation) {
SIGN_IN_WITH_EMAIL_LINK -> ActionCodeResult.SignInWithEmailLink

VERIFY_EMAIL -> ActionCodeResult.VerifyEmail(result.info!!.email)

PASSWORD_RESET -> ActionCodeResult.PasswordReset(result.info!!.email)

RECOVER_EMAIL -> (result.info as ActionCodeEmailInfo).run {
ActionCodeResult.RecoverEmail(email, previousEmail)
}

VERIFY_BEFORE_CHANGE_EMAIL -> (result.info as ActionCodeEmailInfo).run {
ActionCodeResult.VerifyBeforeChangeEmail(email, previousEmail)
}

REVERT_SECOND_FACTOR_ADDITION -> (result.info as ActionCodeMultiFactorInfo).run {
ActionCodeResult.RevertSecondFactorAddition(email, MultiFactorInfo(multiFactorInfo))
}

ERROR -> throw UnsupportedOperationException(result.operation.toString())

else -> throw UnsupportedOperationException(result.operation.toString())
} as T
}
Expand Down
2 changes: 1 addition & 1 deletion firebase-common-internal/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ kotlin {
if (supportedPlatforms.contains(TargetPlatform.Js)) {
getByName("jsMain") {
dependencies {
api(npm("firebase", "10.12.2"))
api(npm("firebase", libs.versions.firebase.npm.get()))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import kotlinx.serialization.encoding.CompositeDecoder

internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) {
StructureKind.CLASS, StructureKind.OBJECT -> decodeAsMap(false)

StructureKind.LIST -> (value as? List<*>).orEmpty().let {
FirebaseCompositeDecoder(it.size, settings) { _, index -> it[index] }
}
Expand All @@ -23,6 +24,7 @@ internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescr
}

is PolymorphicKind -> decodeAsMap(polymorphicIsNested)

else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescr
StructureKind.LIST -> mutableListOf<Any?>()
.also { value = it }
.let { FirebaseCompositeEncoder(settings) { _, index, value -> it.add(index, value) } }

StructureKind.MAP -> mutableListOf<Any?>()
.let { FirebaseCompositeEncoder(settings, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } }

StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor)

is PolymorphicKind -> encodeAsMap(descriptor)

else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ import kotlin.collections.get

internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) {
StructureKind.CLASS, StructureKind.OBJECT -> decodeAsMap(false)

StructureKind.LIST -> decodeAsList()

StructureKind.MAP -> (value as? Map<*, *>).orEmpty().entries.toList().let {
FirebaseCompositeDecoder(it.size, settings) { _, index -> it[index / 2].run { if (index % 2 == 0) key else value } }
}

is PolymorphicKind -> decodeAsMap(polymorphicIsNested)

else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import kotlin.collections.set

internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) {
StructureKind.LIST -> encodeAsList()

StructureKind.MAP -> mutableListOf<Any?>()
.let { FirebaseCompositeEncoder(settings, { value = it.chunked(2).associate { (k, v) -> k to v } }) { _, _, value -> it.add(value) } }

StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor)

is PolymorphicKind -> encodeAsMap(descriptor)

else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ public val EncodedObject.js: Json get() = json(*getRaw().entries.map { (key, val
internal actual fun Any.asNativeMap(): Map<*, *>? {
val json = when (this) {
is Number -> null

is Boolean -> null

is String -> null

is Map<*, *> -> {
if (keys.all { it is String }) {
json(*mapKeys { (key, _) -> key as String }.toList().toTypedArray())
} else {
null
}
}

is Collection<*> -> null

is Array<*> -> null

else -> {
@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE")
this as Json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import kotlin.js.Json

internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescriptor, polymorphicIsNested: Boolean): CompositeDecoder = when (descriptor.kind) {
StructureKind.CLASS, StructureKind.OBJECT -> decodeAsMap(false)

StructureKind.LIST -> decodeAsList()

StructureKind.MAP -> (js("Object").entries(value) as Array<Array<Any>>).let {
FirebaseCompositeDecoder(
it.size,
Expand All @@ -35,6 +37,7 @@ internal actual fun FirebaseDecoderImpl.structureDecoder(descriptor: SerialDescr
}

is PolymorphicKind -> decodeAsMap(polymorphicIsNested)

else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import kotlin.js.json

internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescriptor): FirebaseCompositeEncoder = when (descriptor.kind) {
StructureKind.LIST -> encodeAsList(descriptor)

StructureKind.MAP -> {
val map = json()
var lastKey = ""
Expand All @@ -23,8 +24,11 @@ internal actual fun FirebaseEncoderImpl.structureEncoder(descriptor: SerialDescr
}
}
}

StructureKind.CLASS, StructureKind.OBJECT -> encodeAsMap(descriptor)

is PolymorphicKind -> encodeAsMap(descriptor)

else -> TODO("The firebase-kotlin-sdk does not support $descriptor for serialization yet")
}

Expand Down
2 changes: 1 addition & 1 deletion firebase-common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ kotlin {
if (supportedPlatforms.contains(TargetPlatform.Js)) {
getByName("jsMain") {
dependencies {
api(npm("firebase", "10.12.2"))
api(npm("firebase", libs.versions.firebase.npm.get()))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import dev.gitlive.firebase.apps
import dev.gitlive.firebase.initialize
import dev.gitlive.firebase.runTest
import kotlinx.datetime.Instant
import kotlin.random.Random
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Ignore
Expand Down Expand Up @@ -38,7 +39,7 @@ class FirebaseRemoteConfigTest {
val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize(
context,
FirebaseOptions(
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
applicationId = "1:${Random.nextInt()}:ios:dd1f6688bad7af768c841a",
apiKey = "AIzaSyCK87dcMFhzCz_kJVs2cT2AVlqOTLuyWV0",
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
storageBucket = "fir-kotlin-sdk.appspot.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import dev.gitlive.firebase.initialize
import dev.gitlive.firebase.runBlockingTest
import dev.gitlive.firebase.runTest
import kotlinx.coroutines.delay
import kotlin.random.Random
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand All @@ -30,7 +31,7 @@ class FirebaseCrashlyticsTest {
val app = Firebase.apps(context).firstOrNull() ?: Firebase.initialize(
context,
FirebaseOptions(
applicationId = "1:846484016111:ios:dd1f6688bad7af768c841a",
applicationId = "1:${Random.nextInt()}:ios:dd1f6688bad7af768c841a",
apiKey = "AIzaSyB7pZ7tXymW9WC_ozAppbEs9WBffSmfX9c",
databaseUrl = "https://fir-kotlin-sdk.firebaseio.com",
storageBucket = "fir-kotlin-sdk.appspot.com",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public actual class ServerValue internal actual constructor(
public actual fun increment(delta: Double): ServerValue = ServerValue(NativeServerValue.increment(delta))
}

override fun equals(other: Any?): Boolean = this === other || other is ServerValue && nativeValue == other.nativeValue
override fun equals(other: Any?): Boolean = this === other || (other is ServerValue && nativeValue == other.nativeValue)
override fun hashCode(): Int = nativeValue.hashCode()
override fun toString(): String = "ServerValue($nativeValue)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public actual class ServerValue internal actual constructor(
public actual fun increment(delta: Double): ServerValue = ServerValue(NativeServerValue.increment(delta as NSNumber))
}

override fun equals(other: Any?): Boolean = this === other || other is ServerValue && nativeValue == other.nativeValue
override fun equals(other: Any?): Boolean = this === other || (other is ServerValue && nativeValue == other.nativeValue)
override fun hashCode(): Int = nativeValue.hashCode()
override fun toString(): String = "ServerValue($nativeValue)"
}
Loading
Loading