yarn add @react-native-firebase/appStarting with React Native 0.75+, @react-native-firebase supports Swift Package Manager (SPM) for resolving Firebase iOS SDK dependencies. SPM is enabled by default when the spm_dependency macro is available (injected by React Native >= 0.75) — no configuration needed.
Each RNFB module uses firebase_dependency() (defined in firebase_spm.rb) to declare its Firebase dependencies. This helper automatically chooses between:
| Condition | Resolution | When to use |
|---|---|---|
RN >= 0.75 and $RNFirebaseDisableSPM not set |
SPM (default) | Dynamic linkage / pre-built RN core (use_frameworks! :linkage => :dynamic) |
$RNFirebaseDisableSPM = true in Podfile |
CocoaPods | Static linkage / no pre-built RN core (use_frameworks! :linkage => :static) |
| RN < 0.75 | CocoaPods (automatic fallback) | Older React Native versions without spm_dependency support |
Note on linkage: firebase-ios-sdk SPM products use dynamic linkage. When using
use_frameworks! :linkage => :static, each pod embeds its own copy of Firebase SPM products, causing duplicate symbol errors. Use CocoaPods mode ($RNFirebaseDisableSPM = true) with static linkage.
No changes needed. Just make sure your Podfile uses dynamic linkage:
# Podfile
use_frameworks! :linkage => :dynamicXcode 26 note: If you see build errors about
FirebaseCoreInternalorFirebaseSharedSwiftmodule resolution, add this to your Podfilepost_install:config.build_settings['SWIFT_ENABLE_EXPLICIT_MODULES'] = 'NO'This does NOT disable SPM — it only tells the Swift compiler to use implicit module discovery (the Xcode 16 default) so transitive SPM targets are resolved automatically.
Add this line at the top of your Podfile (before any target block):
# Podfile
$RNFirebaseDisableSPM = trueThis forces all RNFB modules to use traditional s.dependency CocoaPods declarations.
You can use either static or dynamic linkage with this option.
For Expo managed projects, use expo-build-properties to configure linkage and Podfile directives:
// app.json
{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "dynamic"
}
}
]
]
}
}To disable SPM in Expo, add a Podfile directive via a config plugin or app.json:
// app.json
{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static",
"extraPods": []
}
}
]
]
}
}Then create a small config plugin to prepend
$RNFirebaseDisableSPM = true to the generated Podfile, or add it manually if you have ejected.
During pod install, you will see messages indicating which resolution mode is active:
# SPM mode:
[react-native-firebase] RNFBApp: Using SPM for Firebase dependency resolution (products: FirebaseCore)
[react-native-firebase] RNFBAuth: Using SPM for Firebase dependency resolution (products: FirebaseAuth)
# CocoaPods mode:
[react-native-firebase] RNFBApp: SPM disabled ($RNFirebaseDisableSPM = true), using CocoaPods for Firebase dependencies
The firebase_spm.rb helper is loaded by each RNFB podspec via require '../app/firebase_spm'.
This relative path assumes the standard node_modules/@react-native-firebase/ layout. If your
package manager hoists dependencies differently (e.g., pnpm strict mode), you may need to verify
that the require path resolves correctly. The SPM URL is read from
@react-native-firebase/app/package.json at the location of firebase_spm.rb.
- See LICENSE
Built and maintained with 💛 by Invertase.

