Did anyone recently integrated Firebase Firestore ...
# multiplatform
a
Did anyone recently integrated Firebase Firestore in KMP project? I have tried to integrate with this library https://github.com/GitLiveApp/firebase-kotlin-sdk. Though there are not much details in the library git page about integration. But I have tried to implement it by reading various articles. Now my Android application is working fine. But when I try to run the iOS app, it gives below error.
Copy code
> Task :shared:linkDebugFrameworkIosSimulatorArm64 FAILED
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld invocation reported errors

The /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld command returned non-zero exit code: 1.
output:
ld: warning: ignoring duplicate libraries: '-ldl'
ld: framework 'FirebaseFirestore' not found
j
Hehe yeah welcome to the club 😄 I dont have a clean solution other than manually add the cocoapods in the XCode project settings. If anyone else knows anything smoother please help.
😔 1
In theory should also be able to add the cocoapods into your own project, being same as the cocoapods that Firebase Kotlin using in their library. But havent been able to make that work myself.
They using:
Copy code
cocoapods {
            ios.deploymentTarget = "12.0"
            framework {
                baseName = "FirebaseFirestore"
            }
            noPodspec()
            // As of Firebase 10.17 Firestore has moved all ObjC headers to FirebaseFirestoreInternal and the kotlin cocoapods plugin does not handle this well
            // Adding it manually seems to resolve the issue
            pod("FirebaseFirestoreInternal") {
                version = "10.19.0"
            }
            pod("FirebaseFirestore") {
                version = "10.19.0"
                extraOpts += listOf("-compiler-option", "-fmodules")
                useInteropBindingFrom("FirebaseFirestoreInternal")
            }
        }
See https://github.com/GitLiveApp/firebase-kotlin-sdk/blob/master/firebase-firestore/build.gradle.kts
j
If you don't want to use cocoapods, you can do via Swift Package Manager, see Step 4 of https://firebase.google.com/docs/ios/setup
a
My project doesn’t use Cocoapods. So I’m using SPM for libraries. And I have followed the docs of Firebase iOS setup but it didn’t helped. I got a hint, maybe I have to set my shared library’s binary to static. So will try that. Though it was static as initial creation. But due to some build issues, i had to make the static field false. So will try to make it true again. Thanks to both of you for your kind reply
j
Tried to explain how, here is screenshot what you need to have in XCode project settings 🙂 By adding packages described in Firebase iOS setup will work, adding into this particular step in screenshot.
static vs not static didnt help for me. In theory should help using static linking + cocoapods, but ah well the plugin not that good solve this imo yet.
a
Yes these are present. Still error. So trying to make it static as one developer indicated it
j
Whats the error?
a
Error is pasted above
j
Actually can you share your build.gradle.kts too? Apparently you are linking the FirebaseFirestore directly to the Kotlin code, I suspect you'll need to add some -L to your freeCompilerArgs... And also would be good to add freeCompilerArgs += listOf("-Xverbose-phases=Linker") so that you can paste here the actual command line that was used for linking - that should help debugging too
j
@Jan Holešovský If yours working, do you mind pasting it? Would like to learn doing it right way.
j
@Joel Denke I noticed that the difference is that I'm using Firebase directly from Swift (iosApp), not from Kotlin, so I switched to the "help debugging" mode 😄 (that's why asking for the actual command line). In Swift, it worked for me out of the box when I followed the docu I pasted...
j
@Jan Holešovský Oh ok, yeah its an issue that you need to setup google service plist file from FirebaseConfig thingy native in Swift, to configure Kotlin. I would love being able to that directly in my Kotlin code in KMP project. Most in KMP projects using devlive KMP Firebase and not the native things, which gets very complex. Especially since cocapods in KMP not seems to export linking headers + source correct from transtivie gradle deps ...
😅 1
a
@Jan Holešovský Here is the build.gradle.kts file's content
Copy code
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING

plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidLibrary)
    alias(libs.plugins.devtoolsKsp)
    alias(libs.plugins.nativeCoroutines)
    alias(libs.plugins.kotlinxSerialization)
    alias(libs.plugins.sqlDelight)
    id(libs.plugins.buildKonfig.get().toString())
}

kotlin {
    jvmToolchain(11)
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "11"
            }
        }
    }
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
            isStatic = false
        }
    }

    sourceSets {
        all {
            languageSettings {
                optIn("kotlinx.cinterop.ExperimentalForeignApi")
                optIn("kotlin.experimental.ExperimentalObjCName")
            }
        }
        commonMain.dependencies {
            api(libs.kmm.viewmodel.core)
            api(libs.koin.core)
            api(libs.koin.test)

            // Ktor
            implementation(libs.ktor.client.core)
            implementation(libs.ktor.content.negotiation)
            implementation(libs.ktor.serialization.json)
            implementation(libs.ktor.logging)

            // Coroutine
            implementation(libs.kotlinx.coroutines.core)

            // Logger
            implementation(libs.napier.logging)

            // SQLDelight
            implementation(libs.sqldelight.runtime)
            implementation(libs.sqldelight.coroutines.extension)

            // Settings
            implementation(libs.multiplatform.settings)
            implementation(libs.multiplatform.settings.couroutine)

            // Firebase
            implementation(libs.firebase.firestore)
            implementation(libs.firebase.common)
        }
        commonTest.dependencies {
            implementation(libs.kotlin.test)
        }
        androidMain.dependencies {
            implementation(libs.ktor.client.okhttp)

            // SQLDelight
            implementation(libs.sqldelight.android.driver)
        }
        iosMain.dependencies {
            implementation(libs.ktor.client.darwin)

            // SQLDelight
            implementation(libs.sqldelight.ios.driver)
        }
    }
}

android {
    namespace = "com.example"
    compileSdk = 34
    defaultConfig {
        minSdk = 28
    }
}

fun readConfigProperties(): Map<String, String> {
    val items = HashMap<String, String>()

    val fl = rootProject.file("config.properties")

    if (fl.exists()) {
        fl.forEachLine {
            items[it.split("=")[0]] = it.split("=")[1]
        }
    }

    return items
}

val configProperties = readConfigProperties()

buildkonfig {
    packageName = "com.example"

    defaultConfigs {
        buildConfigField(STRING, "API_KEY", configProperties["api_key"])
    }
}

sqldelight {
    databases {
        create("AppDatabase") {
            packageName.set("com.example.shared.cache")
        }
    }
}
Also the corresponding Firebase library references
Copy code
firebase-common = { module = "dev.gitlive:firebase-common", version.ref = "firebaseFirestore" }
firebase-firestore = { module = "dev.gitlive:firebase-firestore", version.ref = "firebaseFirestore" }
iOS app settings for libraries
Actually I have also tried implementing Firestore natively in iOS, that's working perfectly fine. But when I put firebase code in shared module and try to build, the above mentioned error occurs and build fails
j
You havent put the libraries into the linking process of build phases from that screenshot. Also need isStatic = true if I recall correct.
That works for me, sure it doesnt work as it should do, but its working 😄
a
Are you talking about build phases tab like this?
j
Yes 🙂
a
That’s already in state
j
Hmm than it should work. I have pretty much the same as you do.
I guess also double check versions of Firebase is same in KMP Firebase vs iOS Firebase libs as well.
Also did you try build from XCode or from another IDE like Android Studio?
j
@Ahsan Ullah Rasel: Can you please try to add something like:
ios {
binaries {
framework {
baseName = "shared"
// when there is a linking error, show even the command line that lead to the error
freeCompilerArgs += listOf("-Xverbose-phases=Linker")
}
}
}
To the the
kotlin {...}
and re-try the build? That won't fix that, but will give more info - the actual command line the ld was issued with.
a
Making the shared library static solved the problem now. So, will proceed with that now until there aroses any necessary to make the framework non-static. Thanks a lot for your help guys.
784 Views