Trying to hook Firebase into a KMP project? You’ve probably noticed there’s no one‐click solution (or official SDK). Firebase remains essential for authentication, real-time data, and crash reporting.
In this tutorial, you will learn how to:
- Configure and set up multiple Firebase environments for a KMP app
- Use Cocoapod iOS libraries within Kotlin
- Use Kotlin code from Swift
- Have a Kotlin Multiplatform app with full Firebase support
Before you continue
If you’re looking for prebuilt libraries, check out these wonderful solutions!
Check out the code as we progress or use it as a base for your project.
Setup
This tutorial was built with these tools and assumes you have them as well.
- Android Studio Narwhal (Canary) / Intellij IDEA
- Kotlin Multiplatform Plugin
- Xcode 16 (I am using 16.3)
- CocoaPods
1: Create a Kotlin Multiplatform project in Android Studio
Inside Android Studio, click New Project and select Kotlin Multiplatform. You will need the Kotlin Multiplatform Plugin to see this option. You can also use the KMP Wizard to generate a project.
Continue through the flow. In this example, the UI will be shared.
2: Create Dev & Prod Firebase Projects
Log in to your Firebase console and create two projects. One development/staging project and another production project.
At the end, you should see something like this

Two Firebase projects
Set up Android and iOS for both projects
Next, set up your Android and iOS apps in Firebase for each project. Then download each config file. In this tutorial, I suffixed the bundle id with “dev” for development environments. Example:
- com.medium.authtutorial.dev (Development)
- com.medium.authtutorial (Production)
You should have two of each file, one for development and one for production. Put all in the same folder and suffix them with the environment they use. Example:
google-services-development.json
google-services-production.json
GoogleService-Info-Development.plist
GoogleService-Info-Production.plist
3: Configure Firebase on Android (Gradle + JSON)
In this part, we’ll add the Firebase BOM and optional libraries to androidMain
. Firebase auto-initializes on Android, so this will be short and sweet.
Add the required libraries
To get Firebase up and running, add these libraries.
[versions] | |
firebase-bom = "33.14.0" | |
google-services-plugin = "4.4.2" | |
[libraries] | |
android-firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebase-bom" } | |
# Optional, include if using firebase auth | |
android-firebase-auth = { module = "com.google.firebase:firebase-auth" } | |
# Optional, include if using firebase analytics | |
android-firebase-analytics = { module = "com.google.firebase:firebase-analytics" } | |
[plugins] | |
googleServices = { id = "com.google.gms.google-services", version.ref = "google-services-plugin" } |
Link to the Android source set
Remember, these libraries are not built for KMP, so you have to add them to androidMain
, not commonMain
.
plugins { | |
// Other plugins | |
alias(libs.plugins.googleServices) | |
} | |
sourceSets { | |
androidMain.dependencies { | |
implementation(compose.preview) | |
implementation(libs.androidx.activity.compose) | |
implementation(project.dependencies.platform(libs.android.firebase.bom)) | |
implementation(libs.android.firebase.auth) | |
implementation(libs.android.firebase.analytics) | |
} | |
// etc | |
} |
Sync your project and make sure there are no errors.
Add google-service.json to your project
We need Android to locate our JSON file so that Firebase can auto-initialize.
- Under /composeApp/src, create two folders: debug and release.
- Your
google-service.json
files into their respective folders. If you renamed it, make sure to name it back togoogle-service.json

Add google-services.json to debug and release folders
Change the bundle id depending on the environment
Remember, we are setting up Firebase for a development and production environment. If you don’t change the bundle id to match your google-services.json
, Firebase may not initialize.
Inside of build.gradle.kts
, let’s make it so our debug app appends the dev bundle id.
android { | |
// Other configurations... | |
buildTypes { | |
getByName("debug") { | |
isMinifyEnabled = false | |
applicationIdSuffix = ".dev" | |
versionNameSuffix = "-DEBUG" | |
} | |
getByName("release") { | |
isMinifyEnabled = true | |
} | |
} | |
} |
Launch!
On Android, Firebase initializes automatically. So launch your app and check logcat! If you made it this far, 👏 and pat yourself on the back. You’re halfway there!
4: Set up Firebase in iOS (CocoaPods + Kotlin)
In this section, we will initialize iOS Firebase using Kotlin, how exciting! This is due to the power of CocoaPods in our KMP app.
It’s time to become familiar with the iosApp folder. This is where your native iOS application lives. The other folder, iosMain, contains all your iOS Kotlin code. It’s recommended to use the Project view to see this folder inside Android Studio.
Link GoogleService-Info.plist into your iOS App
Firebase needs to link to the right GoogleService-Info.plist file, which we will do in this section. For now, do the following:
- Navigate to the top iosApp folder and make a directory called Firebase
- Drag and drop your two GoogleService-Info files into it
You should end up with something like this.
Set up environment configuration files
Our Xcode project comes with a configuration file located in /Configuration/Config.xcconfig. But we need two config files. One for debug and one for production. This will help us load the correct GoogleService file.
- Navigate to /iosApp/Configuration
- Duplicate
Config.xcconfig
- Name one
Debug.xcconfig
and the otherRelease.xcconfig
- Configure both of these files to your heart’s content
- Finally, add a new variable
GOOGLE_SERVICE
and set it depending on your environment.
GOOGLE_SERVICE=$(SRCROOT)/Firebase/GoogleService-Info-Production.plist
GOOGLE_SERVICE=$(SRCROOT)/Firebase/GoogleService-Info-Development.plist
Link the configuration files inside Xcode
We now need our project to read these new configuration files. We can change this in the project view.
- Open your xcproject file in Xcode
- Click iosApp in the top left
- Click iosApp under project
- Set the
Debug.xcconfig
andRelease.xcconfig
for each environment
⚠️ At this point, you will not see iosApp populated with the Pods-iosApp.xcconfig. That will happen automatically after completing step 4.7
Set up a build script to copy GoogleService-Info.plist
Firebase expects the file to be called GoogleService-Info.plist
. If we try to initialize Firebase with our current file names, we will crash. To fix this
- Under Targets, click iosApp
- Click the + icon and add a New Run Script Phase
- Add the following script
echo "Copying GoogleService located at ${GOOGLE_SERVICE}" | |
if [ -z "${GOOGLE_SERVICE}" ]; then | |
echo "GOOGLE_SERVICE is unset or set to the empty string" | |
exit 1 | |
fi | |
if [ ! -f "${GOOGLE_SERVICE}" ]; then | |
echo "GOOGLE_SERVICE does not exist" | |
exit 1 | |
fi | |
PLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist | |
cp "${GOOGLE_SERVICE}" "${PLIST_DESTINATION}" | |
echo "Copied ${GOOGLE_SERVICE} to ${PLIST_DESTINATION}" |
This script will fail your builds if the GOOGLE_SERVICE variable isn’t found or if it’s blank. Additionally, it will copy the correct plist file into your app.
Adding the GoogleService copying script to Build Phases
Run the app and verify you can build it before continuing.
Remove the embedAndSign task from the Build Phases
While we are in this view, we need to remove a pre-generated script that is incompatible when using Cocoapods for KMP. That script is called “Compile Kotlin Framework”.

Delete the Compile Kotlin Framework script
If you don’t remove this, your will get the fatal error “embedAndSign task can not be used in a project with dependencies to pods”.
Back to Android Studio, add the required libraries
Phew! The iOS setup is almost complete. Next, to use CocoaPods in Kotlin, we need to add the plugin to our libs.versions.toml
[plugins] kotlinCocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
Make sure to wire it up in build.gradle.kts
like other plugins!
plugins { // Other plugins alias(libs.plugins.kotlinCocoapods) }
If you attempt to sync, you will encounter the error “Cocoapods Integration requires pod version to be specified.” We will resolve this in the next step!
Add the CocoaPods block
Inside of build.gradle.kts
, add the CocoaPods block and add the Firebase Core dependency. This will allow us to use iOS Firebase from Kotlin.
// Use the built in cocoapods support to bring in firebase libraries | |
kotlin { | |
// Remove the framework block if its here | |
iosX64() | |
iosArm64() | |
iosSimulatorArm64() | |
cocoapods { | |
summary = "My compose multiplatform app" | |
version = "1.0" | |
homepage = "https://medium.com" | |
ios.deploymentTarget = "16.0" | |
// Add the framework block here | |
framework { | |
baseName = "ComposeApp" | |
isStatic = true | |
} | |
pod("FirebaseCore") { | |
version = "~> 11.13" | |
extraOpts += listOf("-compiler-option", "-fmodules") | |
} | |
} | |
} |
Verify that this creates the composeApp.podspec
file in your composeApp module.
Create the Podfile in iosApp
Time to link our iOS Kotlin code back to our iOS app. In the iosApp directory, create a new Podfile and paste the content below.
target 'iosApp' do use_frameworks! platform :ios, '16.0' pod 'composeApp', :path => '../composeApp' end
Next, run a pod install
where the Podfile is. If you’ve done everything right, your directory will look similar to this

Configuration, Firebase, Podfile
⚠️ Going forward, only use the xcworkspace file. If you have Xcode open, close it and re-open the project with xcworkspace. Do not use the xcodeproj.
Accept the plugin notification to use the xcworkspace file
Back inside Android Studio, you should see a notification to switch to the xcworkspace file. This is very important, make sure you do this! This will enable us to use Kotlin interop with our CocoaPods.

Accept the KMP plugin prompt to use the workspace
If you do not see the prompt above, try running a pod deintegrate
and pod install
again. Without this, you will not be able to use CocoaPods inside of Kotlin.
Initializing Firebase for iOS inside Kotlin
We are in the final home stretch! If we attempt to launch our iOS app through Android Studio or Xcode, we should see this error.
The default Firebase app has not yet been configured. Add FirebaseApp.configure() to your application initialization. This can be done in the App Delegate’s application(_:didFinishLaunchingWithOptions:)….
Firebase does not auto-initialize on iOS, unlike on Android. Let’s follow best practices by hooking into didFinishLaunchingWithOptions
and initializing Firebase.
Inside the iosMain source set (Kotlin code that interacts with iOS), make a new file called KMPInitializer.kt
. Inside, write a simple function that configures Firebase.
import cocoapods.FirebaseCore.FIRApp | |
import kotlinx.cinterop.ExperimentalForeignApi | |
@OptIn(ExperimentalForeignApi::class) | |
fun onDidFinishLaunchingWithOptions() { | |
println("KMP Initializer: Starting setup...") | |
FIRApp.configure() // Call Firebase configure | |
println("KMP Initializer: Firebase project ID: ${FIRApp.defaultApp()?.options!!.projectID()}") | |
} |
As you see, we can use the iOS Firebase SDK from Kotlin. Neat!
Create the AppDelegate.swift file and wire it up
Now, we need to call this function from Swift as there isn’t support for making an app delegates from Kotlin yet.
Inside iosApp (not iosMain), make a new file called AppDelegate.swift
. This will be used to hook into critical app operations. Such as startup, teardown, and push notifications.
import Foundation | |
import UIKit | |
import ComposeApp | |
class AppDelegate: NSObject, UIApplicationDelegate { | |
func application(_ application: UIApplication, | |
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { | |
print("AppDelegate: didFinishLaunchingWithOptions - Calling KMP init.") | |
// Call your kmp initializer kotlin code! | |
KMPInitializerKt.onDidFinishLaunchingWithOptions() | |
return true | |
} | |
// You can add other AppDelegate methods here if needed (like push notifications) | |
} |
Finally, link the delegate inside your app’s entry point.
@main | |
struct iOSApp: App { | |
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate | |
var body: some Scene { | |
WindowGroup { | |
ContentView() | |
} | |
} | |
} |
Job Offers
Launch your app and watch the console output. If successful, you should see something like this
Next Steps
In the following tutorial, we will be integrating Firebase Authentication. This will allow users on iOS and Android to log in, a staple for any app. I will link that article here once it’s posted!
Closing Remarks
That’s it! We’ve successfully linked Firebase to our iOS and Android apps using Kotlin Multiplatform. You now have a template to start your KMP journey using Firebase products.
Check out the source code for this project or connect with me on LinkedIn!
If you found this helpful, leave me a 👏! If you have any comments or feedback, let me know. If you’d like to see a tutorial on anything else, please don’t hesitate to ask. Take care!
This article was previously published on proandroiddev.com.