Closed gchristov closed 2 years ago
You still need to follow the normal steps to add Firebase iOS SDK to your iOS app (https://firebase.google.com/docs/ios/setup).
After you do that you shouldn't be seeing any linking errors.
@suntrix I was following the Swift Package Manager instructions to add Firebase but I was still getting linker errors when executing embedAndSignAppleFrameworkForXcode
with the above error.
What seems to work was to add all Firebase frameworks manually by downloading the bundle and doing this:
val xcf = XCFramework()
val libs = listOf(
"FirebaseFirestore.xcframework",
...
)
val nativeFrameworkPaths =
projectDir.resolve("PATH/TO/FIREBASE/DOWNLOAD").listFiles().filter { it.isDirectory }
.flatMap { it.listFiles().filter { it.isDirectory && libs.contains(it.name) } }
iosTarget("ios") {
binaries {
framework {
baseName = "KmmShared"
xcf.add(this)
val libraryIdentifier = "ios-arm64_i386_x86_64-simulator"
linkerOpts(nativeFrameworkPaths.map { "-F$it/$libraryIdentifier" })
linkerOpts("-ObjC")
}
}
}
I feel like we need a way to tell gradle where to look for the SPM Firebase frameworks, or should that be handled automatically somehow? Am I missing a step somewhere?
Have you tried to not use XCFramework()?
This is how I have it setup in our app that uses this lib.
ios {
binaries {
framework {
baseName = "KmmShared"
isStatic = true
linkerOpts("-ObjC")
}
}
}
Then I just add it to iOS app with -framework KmmShared
& framework search paths in build settings.
Theoretically it should also work as dynamic framework (without isStatic = true
).
How are you installing the Firebase SDK into your iOS project? Is it with Swift Package Manager?
I tried your suggestion above the I'm still getting ld: framework not found FirebaseFirestore
when I install Firebase through Swift Package Manager.
The only thing that works for me is the code that I shared here, which makes me think that Kotlin has no access to the downloaded Firebase SDK if I use SPM for some reason.
Yes we're using SPM in our project & no linking issues in iOS. Are you sure it's actually linked in iOS project?
There's also another thing why this could happen, if you're using iOS-specific SDKs in your iosMain
sources (that would actually explain the issue).
I'm using the standard Xcode -> File -> Add package -> https://github.com/firebase/firebase-ios-sdk
and I choose my project target. Xcode also seems to show autocompletes when I try to import Firebase
for example. I can't launch the app because KMM isn't able to link due to the above error.
if you're using iOS-specific SDKs in your iosMain sources
I don't have iOS-specific SDKs but I do have some dependencies which have iOS implementations, for example Ktor
which needs:
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktorVersion")
}
}
Is this what you meant? Or you meant a Firebase iOS-specific dependency?
In your project, do you have any linker flags set after adding Firebase or are you just following the official instructions?
Also, when I build on Xcode I can see the Firebase dependencies also building so I'd say the SDK should be linked
I'm using the standard Xcode -> File -> Add package ->
https://github.com/firebase/firebase-ios-sdk
and I choose my project target. Xcode also seems to show autocompletes when I try toimport Firebase
for example. I can't launch the app because KMM isn't able to link due to the above error.if you're using iOS-specific SDKs in your iosMain sources
I don't have iOS-specific SDKs but I do have some dependencies which have iOS implementations, for example
Ktor
which needs:val iosMain by getting { dependencies { implementation("io.ktor:ktor-client-ios:$ktorVersion") } }
Is this what you meant? Or you meant a Firebase iOS-specific dependency?
I meant Firebase iOS-specific SDKs.
I remember that I had to link the iOS frameworks when we used to have some Kotlin code in iosMain sources that were calling the Firebase SDKs directly or through the .ios
properties in the multiplatform code.
In your project, do you have any linker flags set after adding Firebase or are you just following the official instructions?
Yes, we followed the official instructions.
I am having the same issue, i followed the ios instructions and receiving ld: framework not found FirebaseFirestore
I don’t use iOS specific SDKs in iosMain and am just linking this library in commonMain and accessing Firestore from the shared code.
Obviously on Android we have to specifically link and initialise Firebase and iOS should be the same, so I am expecting to have to tell the Kotlin compiler where to look for the dependencies during the emberAndSignXcodeFramework task, so there must be a step we’re missing somewhere…
@suntrix Do you have a working project we can take a look at?
My plan is to try and setup a basic app with just this library to rule out any multimodule-specific issues I may be hitting.
yes a simple sample will solve this issue. Trying to solve this for few days now using cocoapods
I tried this with a new vanilla project and am getting the same error. Steps to reproduce are:
Regular Framework
for the setting iOS Framework Distribution
classpath("com.google.gms:google-services:4.3.10")
to the dependencies
section of buildscript
under MyApplication/build.gradle.kts
apply(plugin = "com.google.gms.google-services")
and implementation(platform("com.google.firebase:firebase-bom:30.0.1"))
to appAndroid/build.gradle.kts
dependencies { implementation("dev.gitlive:firebase-firestore:1.6.1") }
to commonMain
in shared/build.gradle.kts
At this point the Android app builds but complains about a missing google-services.json
which is expected and not an issue.
File -> Add Packages
on Xcode and add https://github.com/firebase/firebase-ios-sdk
FirebaseFirestore
from the available SDKs and wait until Xcode finishes initialisingld: framework not found FirebaseFirestore
@suntrix @nbransby My suspicion is that we need extra steps for the iOS setup but I can't quite figure out what they are. Any other suggestions or maybe a small working example app?
I can repro this issue when I setup a sample app. I'll check what I did in our project to not see this issue & let you know.
When I set the framework to static the linker issue goes away.
kotlin {
android()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "AppShared"
isStatic = true
}
}
sourceSets {
...
}
Also one of the devs in my team have created https://github.com/akaffenberger/firebase-ios-sdk-xcframeworks :)
isStatic = true did the magic ! also note that this dev.gitlive:firebase-config
is causing another issue on ios but im just commenting its use for now
I can confirm that setting isStatic = true
has solved it both in my test project and real multi-module app, thanks! 🙌 @suntrix would you mind sharing a 1-line sentence of why this is necessary?
As a side-effect I assume this means the final shared KMM framework that is linked to iOS is now a static
one, rather than dynamic, right?
So essentially we have 2 ways of doing this (with their own pros/cons):
static framework (isStatic = true
)
dynamic framework (isStatic = false
)
TBH - linking statically something that needs to be initialised at app start makes sense, because Apple doesn't recommend using too many dynamic frameworks in iOS apps & also there's noticeable latency when loading a bunch of dynamic frameworks at app start.
Awesome, thanks for the clarifications!
I think it might be helpful to update the README
with some setup instructions, since there are a few similar issues. I've linked some basic instructions here which as of today produce a working project (have also linked the relevant versions I'm using) 👍
I'll close this for now as I can confirm my project works both on the Intel Mac and on the M1.
That would be a question for @nbransby since he's the owner of this project, I'm just contributing my free time :)
The issue is not specific to this library but to KMM which still is missing a few things.
WOW THIS THREAD IS A LIFE SAVER.
Thanks a bunch @suntrix and @gchristov for finding the fix and posting it here!
I think we should definitely get this stuff added to the README as it is essential to get the project working and googling for the errors this solves leads to old posts with answers that didn't work for me.
Thank the heavems for this thread!
Any possible way to create dynamic XCFramework(isStatic = false
) with this lib?
Any possible way to create dynamic XCFramework(
isStatic = false
) with this lib?
isStatic = true
results in many thousands of warnings in XCode during Generate YourApp.app.dSym
such as the following
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.NativePointed#<get-rawPtr>(){}kotlin.native.internal.NativePtr
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop#interpretOpaquePointed(kotlin.native.internal.NativePtr){}kotlinx.cinterop.NativePointed
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.CPointer#<get-value>(){}kotlin.native.internal.NonNullNativePtr
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop#<get-ptr>__at__0:0(){0§<kotlinx.cinterop.CPointed>}kotlinx.cinterop.CPointer<0:0>
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop#<get-rawValue>__at__kotlinx.cinterop.CPointer<*>?(){}kotlin.native.internal.NativePtr
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.CVariable.Type#<init>(kotlin.Long;kotlin.Int){}
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.CVariable.Type#<get-size>(){}kotlin.Long
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.CVariable.Type#<get-align>(){}kotlin.Int
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.CStructVar.Type#<init>(kotlin.Long;kotlin.Int){}
warning: (arm64) could not find object file symbol for symbol _kfun:kotlinx.cinterop.NativePlacement#alloc(kotlin.Int;kotlin.Int){}kotlinx.cinterop.NativePointed
Because of the sheer quantity of warnings, it causes XCode to hang. Any idea of how to silence these warnings at least?
Hm, I don't just get those warnings while generating dsyms, I get them for each build... And yes, it seems to be a bit much for Xcode, for my little project its 36k+ warnings. 😅
I found a workaround that eliminates the warnings, though it is not ideal.
In your project's build settings, find Debug Information Format
and under Debug
select DWARF
and leave Release
as DWARF with dSYM File
.
This eliminates the warnings, but it isn't ideal for the stack trace during debugging, I think.
This eliminates the warnings, but it isn't ideal for the stack trace during debugging, I think.
Yes, it makes setting breakpoints for Kotlin/native code in Android Studio etc. impossible.
The warnings are only a problem for Xcode, not Android Studio (go figure 😁 ), so what I'm doing now is enabling the setting in Xcode while implementing Kotlin/native stuff, then build and debug via Android Studio, and then disable DWARF with dSYM
again when back in Xcode. Tedious, but it works.
Another side note: I found, that the warnings don't seem to affect Xcode as long as I don't have the problem view (or the build view) open during build.
I'm using the standard Xcode -> File -> Add package ->
https://github.com/firebase/firebase-ios-sdk
and I choose my project target. Xcode also seems to show autocompletes when I try toimport Firebase
for example. I can't launch the app because KMM isn't able to link due to the above error.if you're using iOS-specific SDKs in your iosMain sources
I don't have iOS-specific SDKs but I do have some dependencies which have iOS implementations, for example
Ktor
which needs:val iosMain by getting { dependencies { implementation("io.ktor:ktor-client-ios:$ktorVersion") } }
Is this what you meant? Or you meant a Firebase iOS-specific dependency?
I meant Firebase iOS-specific SDKs. I remember that I had to link the iOS frameworks when we used to have some Kotlin code in iosMain sources that were calling the Firebase SDKs directly or through the
.ios
properties in the multiplatform code.In your project, do you have any linker flags set after adding Firebase or are you just following the official instructions?
Yes, we followed the official instructions.
@suntrix Apologies for coming back to this after such a long time.
I'm in the process of migrating my project to KMM
using the gitlive firebase sdk
and I'm having trouble accessing the .ios
property inside the iosMain
module.
This seems to happen because I'm using SPM
instead of CocoaPods
and I'm really struggling to find a fix.
According to your comment, you had a similar issue and I was wondering if you somehow remember what it was. Thanks!
I believe this is due to the iOS arch "commonization" feature not being enabled. Right now, your IDE isn't showing autocomplete and is showing errors, but if the code were correct, it would compile via the command line. If you were to create a file under a specific iOS arch folder like iosArm64
vs iosMain
, then the IDE would be happy. However, you can enable commonization so that the IDE is happy while writing in iosMain
.
Try adding this line to your gradle.properties
file at your project root:
kotlin.mpp.enableCInteropCommonization=true
@walkingbrad That did the trick! Thank you so much, you're a life saver!
I have managed to setup my multiplatform project with this library for Android with no issues and it works great so far! However, iOS is giving me the following error when I try to build the app
which I believe is similar to some of the other issues I've seen in this repo.
Would it be possible to include working setup instructions for iOS?
My setup for Android is exactly the same as the usual Firebase guide so I imagine iOS would be the same but I'm probably missing an important step somewhere in between. I should also mention that I have a multi-module project and Firebase is setup as a standalone module to be linked to the rest of the app.
Thanks very much for building the SDK and I'm hoping to have iOS working the same way as Android 🙏