I am trying to build Xcode preview in kotlin multiplatform project when using FirebaseFirestore with CocoaPods.
With the following gradle files everything works fine, app runs & preview runs.
Module build.gradle.kts
:
plugins {
//trick: for the same plugin versions in all sub-modules
alias(libs.plugins.androidApplication).apply(false)
alias(libs.plugins.androidLibrary).apply(false)
alias(libs.plugins.kotlinAndroid).apply(false)
alias(libs.plugins.kotlinMultiplatform).apply(false)
alias(libs.plugins.kotlinCocoapods).apply(false)
id("com.google.gms.google-services") version "4.4.0" apply false
}
buildscript {
dependencies {
classpath("dev.icerock.moko:resources-generator:0.23.0")
}
}
gradle.properties
:
#Gradle
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
org.gradle.caching=true
org.gradle.configuration-cache=true
#Kotlin
kotlin.code.style=official
#Is forced by Moko Resources library (specificaly by "androidMain.dependsOn(...)")
kotlin.mpp.applyDefaultHierarchyTemplate=false
#Android
android.useAndroidX=true
android.nonTransitiveRClass=true
Shared build.gradle.kts
:
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinCocoapods)
alias(libs.plugins.androidLibrary)
id("com.google.devtools.ksp") version "1.9.20-1.0.14"
id("com.rickclephas.kmp.nativecoroutines") version "1.0.0-ALPHA-21"
kotlin("plugin.serialization") version "1.9.20"
id("dev.icerock.mobile.multiplatform-resources")
}
kotlin {
androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "11"
}
}
}
iosX64()
iosArm64()
iosSimulatorArm64()
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of("11"))
}
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "16.0"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
isStatic = false
export("dev.icerock.moko:resources:0.23.0")
export("dev.icerock.moko:graphics:0.9.0")
}
pod("FirebaseCore", linkOnly = true)
pod("FirebaseAuth", linkOnly = true)
//pod("FirebaseCoreExtension", linkOnly = true)
//pod("FirebaseSharedSwift", linkOnly = true)
//pod("FirebaseFirestore", linkOnly = true)
}
sourceSets {
sourceSets.all {
languageSettings.optIn("kotlin.experimental.ExperimentalObjCName")
languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi")
}
androidMain {
dependsOn(commonMain.get()) // Moko Resources needs this dependency
}
// Implicitly specifies dependencies because Moko Resources disabled the default hierarchy template via "androidMain.dependsOn(...)" above
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain.get())
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
}
commonMain.dependencies {
api("com.rickclephas.kmm:kmm-viewmodel-core:1.0.0-ALPHA-15")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
api("dev.icerock.moko:resources:0.23.0")
api("dev.icerock.moko:resources-compose:0.23.0")
api("org.lighthousegames:logging:1.3.0")
implementation("dev.gitlive:firebase-auth:1.10.4")
//implementation("dev.gitlive:firebase-firestore:1.10.4")
}
commonTest.dependencies {
implementation(libs.kotlin.test)
implementation("dev.icerock.moko:resources-test:0.23.0")
}
}
}
android {
namespace = "com.example.project"
compileSdk = 34
defaultConfig {
minSdk = 24
}
}
multiplatformResources {
multiplatformResourcesPackage = "com.example.project"
iosBaseLocalizationRegion = "en"
}
// This resolves Moko Resources issue where the build order could be wrong
tasks.configureEach {
if (name == "generateMRcommonMain") {
dependsOn("kspKotlinIosX64")
dependsOn("kspKotlinIosArm64")
dependsOn("kspKotlinIosSimulatorArm64")
}
if (name == "generateMRiosX64Main") {
dependsOn("kspKotlinIosX64")
}
if (name == "generateMRiosArm64Main") {
dependsOn("kspKotlinIosArm64")
}
if (name == "generateMRiosSimulatorArm64Main") {
dependsOn("kspKotlinIosSimulatorArm64")
}
}
Podfile
:
target 'iosApp' do
use_frameworks!
platform :ios, '16.0'
pod 'shared', :path => '../shared'
pod 'KMPNativeCoroutinesCombine', '1.0.0-ALPHA-21'
pod 'KMMViewModelSwiftUI', '1.0.0-ALPHA-15'
# Required by shared firebase dependencies
pod 'FirebaseAuth'
pod 'FirebaseFirestore'
end
But if i uncomment the Firestore lines:
pod("FirebaseCoreExtension", linkOnly = true)
pod("FirebaseSharedSwift", linkOnly = true)
pod("FirebaseFirestore", linkOnly = true)
and
implementation("dev.gitlive:firebase-firestore:1.10.4")
Then even the app now fails to build with an error:
ld: Undefined symbols:
_FIRFirestoreErrorDomain, referenced from:
_cocoapods_FirebaseFirestore_FIRFirestoreErrorDomain_getter_wrapper0 in libdev.gitlive:firebase-firestore-cinterop-FirebaseFirestore-cache.a[2](libdev.gitlive:firebase-firestore-cinterop-FirebaseFirestore-cache.a.o)
_OBJC_CLASS_$_FIRDocumentChange, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRDocumentReference, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRDocumentSnapshot, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRFieldPath, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRFieldValue, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRFirestore, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRGeoPoint, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRQuerySnapshot, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
_OBJC_CLASS_$_FIRTimestamp, referenced from:
in libdev.gitlive:firebase-firestore-cache.a[2](libdev.gitlive:firebase-firestore-cache.a.o)
Note that I am using a dynamic framework for preview to work and link only pods to solve missing/duplicate references.
I am not using FirebaseFirestore outside of commonMain
and do not intend to.
I FINALLY figured it out. The problem is with the version of the firebase pods. Kotlin firebase library is not compatible with latest swift firebase library, although I did not find it anywhere specified, but it just does not work.
The swift version
10.12
is working with current latest kotlin version1.10.4
.So I just specified the versions of pods and increased the java heap size.
Shared
build.gradle.kts
:Podfile
:gradle.properties
:There is no longer a need to explicitly add dependencies of pods, like
FirebaseCore
, etc.I figured it out thanks to an issue thread on kotlin library github. It is only very remotely related, but it might help.