react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

Build error on expo 54 / react native 0.81 (upstream Expo issue, workaround via build properties below)

Open mzaien opened this issue 4 months ago • 75 comments

Maintainer edit: there is a workaround below, and you should subscribe to the expo issue for updates ---> https://github.com/invertase/react-native-firebase/issues/8657#issuecomment-3236409106

Issue

build fails on the new preview of expo 54 / react native 0.81 Image

Project Files

Javascript

Click To Expand

package.json:

using latest version using bunx expo install expo@next --check and updated firebase to latest

 "@react-native-firebase/analytics": "^23.0.1",
    "@react-native-firebase/app": "^23.0.1",
    "@react-native-firebase/messaging": "^23.0.1",

firebase.json for react-native-firebase v6:

{
  "react-native": {
    "messaging_ios_auto_registration_for_remote_messages": true
  }
}

iOS

Click To Expand

ios/Podfile:

  • [ ] I'm not using Pods
  • [x] I'm using Pods and my Podfile looks like:
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")

require 'json'
podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}

ENV['RCT_NEW_ARCH_ENABLED'] = '0' if podfile_properties['newArchEnabled'] == 'false'
ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
ENV['RCT_USE_RN_DEP'] = '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
ENV['RCT_USE_PREBUILT_RNCORE'] = '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true' && podfile_properties['newArchEnabled'] != 'false'
platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'

prepare_react_native_project!

target 'App' do
  use_expo_modules!
# @generated begin add Moyasar SDK to Podfile - expo prebuild (DO NOT MODIFY) sync-40c0c3dbaa1d7876902dba7e94b7185d377221a0
pod 'MoyasarSdk', git: 'https://github.com/moyasar/moyasar-ios-pod.git', :tag => 'v3.0.0'
# @generated end add Moyasar SDK to Podfile

  if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1'
    config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
  else
    config_command = [
      'npx',
      'expo-modules-autolinking',
      'react-native-config',
      '--json',
      '--platform',
      'ios'
    ]
  end

  config = use_native_modules!(config_command)

  use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
  use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']

  use_react_native!(
    :path => config[:reactNativePath],
    :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/..",
    :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
  )

  post_install do |installer|
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false,
      :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
    )
  end
end

AppDelegate.swift:

import Expo
// @generated begin Intercom header - expo prebuild (DO NOT MODIFY) sync-f6fd06e08d30c2c66260b72f45072d393b20a2dc
import intercom_react_native
// @generated end Intercom header
import Security
import FirebaseCore
import React
import ReactAppDependencyProvider


...

    window = UIWindow(frame: UIScreen.main.bounds)
// @generated begin @react-native-firebase/app-didFinishLaunchingWithOptions - expo prebuild (DO NOT MODIFY) sync-10e8520570672fd76b2403b7e1e27f5198a6349a
clearKeychainIfNecessary()
FirebaseApp.configure()
// @generated end @react-native-firebase/app-didFinishLaunchingWithOptions

Environment

Click To Expand

react-native info output:

System:
  OS: macOS 15.6
  CPU: (12) arm64 Apple M2 Pro
  Memory: 308.64 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 22.17.0
    path: ~/.local/share/mise/installs/node/22.17.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.yarn/bin/yarn
  npm:
    version: 10.9.2
    path: ~/.local/share/mise/installs/node/22.17.0/bin/npm
  Watchman:
    version: 2025.08.11.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.5
      - iOS 18.5
      - macOS 15.5
      - tvOS 18.5
      - visionOS 2.5
      - watchOS 11.5
  Android SDK: Not Found
IDEs:
  Android Studio: 2025.1 AI-251.26094.121.2512.13840223
  Xcode:
    version: 16.4/16F6
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.11
    path: /usr/bin/javac
  Ruby:
    version: 3.4.5
    path: /opt/homebrew/opt/ruby/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.1.3
    wanted: ^15.1.2
  react:
    installed: 19.1.0
    wanted: 19.1.0
  react-native:
    installed: 0.81.0
    wanted: 0.81.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: true
  • Platform that you're experiencing the issue on:
    • [x] iOS
    • [ ] Android
    • [ ] iOS but have not tested behavior on Android
    • [ ] Android but have not tested behavior on iOS
    • [ ] Both
  • react-native-firebase version you're using that has this issue:
    • e.g. 5.4.3
  • Firebase module(s) you're using that has the issue:
    • e.g. Instance ID
  • Are you using TypeScript?
    • Y/N & VERSION

mzaien avatar Aug 18 '25 03:08 mzaien

Hi there, can you try "Allow Non-modular Includes in Framework Modules" in your project's build settings?

MichaelVerdon avatar Aug 18 '25 09:08 MichaelVerdon

Can confirm this too. Manually changing Xcode settings in an Expo Managed workflow isn’t ideal and I wasn’t able to solve this.

JustJoostNL avatar Aug 19 '25 17:08 JustJoostNL

I made a plugin to make it work with expo, got the fixes from https://github.com/invertase/react-native-firebase/issues/6933

const {withPodfile} = require('@expo/config-plugins');
const {applyImplementation} = require('./utils');

module.exports = function withSwiftKeychainClear(config) {
    return withPodfile(config, config => {
        // firebase static framework
        config.modResults.contents = applyImplementation(
            config.modResults.contents,
            "use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']",
            '  $RNFirebaseAsStaticFramework = true',
        );
        config.modResults.contents = applyImplementation(
            config.modResults.contents,
            `react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false,
      :ccache_enabled => podfile_properties['apple.ccacheEnabled'] == 'true',
    )`,
            `    installer.pods_project.build_configurations.each do |config|
      config.build_settings["CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"] = "YES"
    end`,
        );
        return config;
    });
};
 

applyImplementation code

function applyImplementation(contents, find, add, replace, addBefore = false) {
    // Make sure the project does not have the settings already
    if (!contents.includes(add)) {
        if (replace) {
            return contents.replace(find, add);
        }
        if (addBefore) {
            return contents.replace(find, `${add}\n${find}`);
        }
        return contents.replace(find, `${find}\n${add}`);
    }

    return contents;
}

module.exports = {
    applyImplementation,
};

mzaien avatar Aug 20 '25 02:08 mzaien

Hey there @mzaien does this mean your issue is resolved?

MichaelVerdon avatar Aug 20 '25 06:08 MichaelVerdon

While the config plugin solution will probably work, I don’t think it is something for the long-term, because everyone has to add that. Ideally some fix gets implemented in this library.

JustJoostNL avatar Aug 20 '25 07:08 JustJoostNL

@MichaelVerdon I thought I was done but got new errors

❌  (node_modules/@react-native-firebase/messaging/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h:26:21)

  24 | @interface RNFBMessagingAppDelegate : NSObject <UIApplicationDelegate>
  25 | 
> 26 | @property _Nullable RCTPromiseRejectBlock registerPromiseRejecter;
     |                     ^ declaration of 'RCTPromiseRejectBlock' must be imported from module 'RNFBApp.RNFBAppModule' before it is required
  27 | @property _Nullable RCTPromiseResolveBlock registerPromiseResolver;
  28 | @property(nonatomic, strong) NSCondition *conditionBackgroundMessageHandlerSet;
  29 | @property(nonatomic) BOOL backgroundMessageHandlerSet;

› Compiling @react-native-firebase/messaging Pods/RNFBMessaging » RNFBMessaging+AppDelegate.m

❌  (node_modules/@react-native-firebase/messaging/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h:26:21)

  24 | @interface RNFBMessagingAppDelegate : NSObject <UIApplicationDelegate>
  25 | 
> 26 | @property _Nullable RCTPromiseRejectBlock registerPromiseRejecter;
     |                     ^ declaration of 'RCTPromiseRejectBlock' must be imported from module 'RNFBApp.RNFBAppModule' before it is required
  27 | @property _Nullable RCTPromiseResolveBlock registerPromiseResolver;
  28 | @property(nonatomic, strong) NSCondition *conditionBackgroundMessageHandlerSet;
  29 | @property(nonatomic) BOOL backgroundMessageHandlerSet;


❌  (node_modules/@react-native-firebase/messaging/ios/RNFBMessaging/RNFBMessaging+AppDelegate.m:101:10)

   99 |   if (_registerPromiseResolver != nil) {
  100 |     _registerPromiseResolver(@(
> 101 |         [RCTConvert BOOL:@([UIApplication sharedApplication].isRegisteredForRemoteNotifications)]));
      |          ^ declaration of 'RCTConvert' must be imported from module 'RNFBApp.RCTConvert_FIRApp' before it is required
  102 |     _registerPromiseResolver = nil;
  103 |     _registerPromiseRejecter = nil;
  104 |   }

› Compiling react-native-device-info Pods/RNDeviceInfo » RNDeviceInfo-dummy.m
› Compiling react-native-device-info Pods/RNDeviceInfo » DeviceUID.m
› Compiling @react-native-firebase/messaging Pods/RNFBMessaging » RNFBMessagingModule.m

❌  (node_modules/@react-native-firebase/messaging/ios/RNFBMessaging/RNFBMessaging+AppDelegate.h:26:21)

  24 | @interface RNFBMessagingAppDelegate : NSObject <UIApplicationDelegate>
  25 | 
> 26 | @property _Nullable RCTPromiseRejectBlock registerPromiseRejecter;
     |                     ^ declaration of 'RCTPromiseRejectBlock' must be imported from module 'RNFBApp.RNFBAppModule' before it is required
  27 | @property _Nullable RCTPromiseResolveBlock registerPromiseResolver;
  28 | @property(nonatomic, strong) NSCondition *conditionBackgroundMessageHandlerSet;
  29 | @property(nonatomic) BOOL backgroundMessageHandlerSet;


❌  (node_modules/@react-native-firebase/messaging/ios/RNFBMessaging/RNFBMessagingModule.m:33:1)

  31 | #pragma mark Module Setup
  32 | 
> 33 | RCT_EXPORT_MODULE();
     | ^ type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int [-Wimplicit-int]
  34 | 
  35 | - (id)init {
  36 |   self = [super init];

mzaien avatar Aug 20 '25 07:08 mzaien

I'm having a similar issue with Expo 53. How are you guys installing firebase with expo 53 and new arch?

jrhager84 avatar Aug 26 '25 03:08 jrhager84

Running into similar issues, looks like a fix is slated for 0.81.1 https://github.com/facebook/react-native/pull/53432

› Compiling @react-native-firebase/app-check Pods/RNFBAppCheck » RNFBAppCheckProviderFactory.m

❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app/ios/RNFBApp/RCTConvert+FIRApp.h:19:9)

  17 |
  18 | #import <FirebaseCore/FirebaseCore.h>
> 19 | #import <React/RCTConvert.h>
     |         ^ include of non-modular header inside framework module 'RNFBApp.RCTConvert_FIRApp': '/Users/anudit/Documents/GitHub/omnidapp/ios/Pods/Headers/Public/React-Core/React/RCTConvert.h' [-Werror,-Wnon-modular-include-in-framework-module]
  20 |
  21 | @interface RCTConvert (FIRApp)
  22 | + (FIRApp *)firAppFromString:(NSString *)appName;


❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app/ios/RNFBApp/RCTConvert+FIROptions.h:19:9)

  17 |
  18 | #import <FirebaseCore/FirebaseCore.h>
> 19 | #import <React/RCTConvert.h>
     |         ^ include of non-modular header inside framework module 'RNFBApp.RCTConvert_FIROptions': '/Users/anudit/Documents/GitHub/omnidapp/ios/Pods/Headers/Public/React-Core/React/RCTConvert.h' [-Werror,-Wnon-modular-include-in-framework-module]
  20 |
  21 | @interface RCTConvert (FIROptions)
  22 | + (FIROptions *)convertRawOptions:(NSDictionary *)rawOptions;


❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app/ios/RNFBApp/RNFBAppModule.h:20:9)

  18 | #import <Foundation/Foundation.h>
  19 |
> 20 | #import <React/RCTBridgeModule.h>
     |         ^ include of non-modular header inside framework module 'RNFBApp.RNFBAppModule': '/Users/anudit/Documents/GitHub/omnidapp/ios/Pods/Headers/Public/React-Core/React/RCTBridgeModule.h' [-Werror,-Wnon-modular-include-in-framework-module]
  21 |
  22 | @interface RNFBAppModule : NSObject <RCTBridgeModule>
  23 |


❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app/ios/RNFBApp/RNFBRCTEventEmitter.h:19:9)

  17 |
  18 | #import <Foundation/Foundation.h>
> 19 | #import <React/RCTEventEmitter.h>
     |         ^ include of non-modular header inside framework module 'RNFBApp.RNFBRCTEventEmitter': '/Users/anudit/Documents/GitHub/omnidapp/ios/Pods/Headers/Public/React-Core/React/RCTEventEmitter.h' [-Werror,-Wnon-modular-include-in-framework-module]
  20 |
  21 | /**
  22 |  * Listeners for Firebase events and emits them to the JS layer


❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app/ios/RNFBApp/RNFBSharedUtils.h:22:9)

  20 |
  21 | #import <FirebaseCore/FirebaseCore.h>
> 22 | #import <React/RCTBridgeModule.h>
     |         ^ include of non-modular header inside framework module 'RNFBApp.RNFBSharedUtils': '/Users/anudit/Documents/GitHub/omnidapp/ios/Pods/Headers/Public/React-Core/React/RCTBridgeModule.h' [-Werror,-Wnon-modular-include-in-framework-module]
  23 |
  24 | #ifdef DEBUG
  25 | #define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);


❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app/ios/RNFBApp/RNFBUtilsModule.h:21:9)

  19 | #import <Photos/Photos.h>
  20 |
> 21 | #import <React/RCTBridgeModule.h>
     |         ^ include of non-modular header inside framework module 'RNFBApp.RNFBUtilsModule': '/Users/anudit/Documents/GitHub/omnidapp/ios/Pods/Headers/Public/React-Core/React/RCTBridgeModule.h' [-Werror,-Wnon-modular-include-in-framework-module]
  22 |
  23 | @interface RNFBUtilsModule : NSObject <RCTBridgeModule>
  24 |


❌  (/Users/anudit/Documents/GitHub/omnidapp/node_modules/@react-native-firebase/app-check/ios/RNFBAppCheck/RNFBAppCheckProviderFactory.m:19:9)

  17 |
  18 | #import "RNFBAppCheckProviderFactory.h"
> 19 | #import "RNFBApp/RNFBSharedUtils.h"
     |         ^ could not build module 'RNFBApp'
  20 |
  21 | @implementation RNFBAppCheckProviderFactory
  22 |

› Compiling @react-native-firebase/app-check Pods/RNFBAppCheck » RNFBAppCheckProvider.m

anudit avatar Aug 26 '25 03:08 anudit

Historically, setting

CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES

in XCode was a temporary workaround maybe this could help for now?

Also considering fixes linked by @anudit I suspect this is a react native issue and something we may not be able to address here unfortunately.

MichaelVerdon avatar Aug 26 '25 11:08 MichaelVerdon

Setting useFrameworks to static and buildReactNativeFromSource to true in the expo config seems to solve this issue:

[
  "expo-build-properties",
  {
    ios: {
      useFrameworks: "static",
      buildReactNativeFromSource: true,
    },
  },
]

Verified by using expo 54.0.0-preview.10 and react-native 0.81.1. A better solution is being worked on by expo.

LeonDvlpmnt avatar Aug 29 '25 09:08 LeonDvlpmnt

That's great to hear with regard to a workaround, that flag you used buildReactNativeFromSource seems to indicate this is some teething problems related the new precompiled frameworks.

Sounds like it's not actionable here - I encourage people to subscribe to that upstream issue helpfully provided by @LeonDvlpmnt (thanks!)

mikehardy avatar Aug 29 '25 16:08 mikehardy

Still running into this with expo@54, [email protected] & [email protected]

anudit avatar Sep 10 '25 23:09 anudit

Yep same issue. Also mentioned here https://github.com/expo/expo/issues/39233

cheraff avatar Sep 11 '25 04:09 cheraff

Having the same issue after migration to Expo 54

RomanSytnyk avatar Sep 11 '25 08:09 RomanSytnyk

Can confirm, seeing an error.

sohail-wayland avatar Sep 11 '25 10:09 sohail-wayland

@MichaelVerdon @mzaien looks like expo fixed things on their end https://github.com/expo/expo/issues/39233#issuecomment-3281166075 but still running into the issue with the new version of [email protected]

anudit avatar Sep 11 '25 16:09 anudit

@MichaelVerdon @mzaien looks like expo fixed things on their end https://github.com/expo/expo/issues/39233#issuecomment-3281166075 but still running into the issue with the new version of [email protected]

For me it worked and I'm not having any issues

mzaien avatar Sep 11 '25 18:09 mzaien

@MichaelVerdon @mzaien looks like expo fixed things on their end expo/expo#39233 (comment) but still running into the issue with the new version of [email protected]

For me it worked and I'm not having any issues

Are you using any of the patches mentioned in this issue? I'm using Expo 54.0.1 and still got the error.

vilsongabriel avatar Sep 11 '25 20:09 vilsongabriel

Best fix I've found so far is setting buildReactNativeFromSource to true in expo-build-properties. Not ideal but hopefully can get you up and running until it's fixed.

"expo-build-properties", { ios: { useFrameworks: "static", deploymentTarget: "15.1", buildReactNativeFromSource: true, },

JoshRozin avatar Sep 11 '25 23:09 JoshRozin

@vilsongabriel i’m using the one @JoshRozin mentioned

mzaien avatar Sep 12 '25 07:09 mzaien

@mzaien don't close this issue, buildReactNativeFromSource should not be the final solution. This is not an Expo only issue, this is the new prebuild react native option as you can see here: https://reactnative.dev/blog/2025/08/12/react-native-0.81#experimental-precompiled-ios-builds

danieloprado avatar Sep 12 '25 08:09 danieloprado

@mikehardy @mzaien I do not think this should be closed, this is still an issue. buildReactNativeFromSource is not a feature that is going away, disabling it is not a solution. Thanks!

anudit avatar Sep 12 '25 13:09 anudit

https://github.com/invertase/react-native-firebase/issues/8657#issuecomment-3284313384

Agreed. Should not be the final fix. Just mentioned it because it worked for me.

JoshRozin avatar Sep 12 '25 15:09 JoshRozin

same thing happening to me

1forh avatar Sep 12 '25 21:09 1forh

+1

Also not sure if buildReactNativeFromSource is a viable fix.

RohovDmytro avatar Sep 13 '25 13:09 RohovDmytro

For me neither the buildReactNativeFromSource or Allow Non-modular Includes in Framework Modules works

bfzli avatar Sep 13 '25 18:09 bfzli

+1 Can confirm that buildReactNativeFromSource is a viable fix, but absolutely not ideal long term.

danielrakaczki1 avatar Sep 15 '25 09:09 danielrakaczki1

Hi All :)

To clarify a bit here - the problem is that when we're building frameworks as we do when setting use_frameworks! in our pod file through the Expo build setting ("useFrameworks": "static"), we're requiring some additional rules for each pod, especially that it should not export header files from other target's private properties.

This is the problem here, since Firebase implements some RCTConvert'ers that ends up exposing a few React Native header files. The problem is NOT Firebase, it is an issue with React Native's headers not yet being 100% modular (they often end up include C++ code that is not valid Objective-c) causing the issue we see here.

This is being worked on, but is a much bigger issue to solve for now - also considering that we're moving towards a world without Cocoapods in the near future (Cocoapods are being deprecated).

I'm working on a solution where this is a bit easier to handle in Expo without all of the above tricks before we get a real modular set of headers in React Native.

chrfalch avatar Sep 15 '25 10:09 chrfalch

Setting useFrameworks to static and buildReactNativeFromSource to true in the expo config seems to solve this issue:

[
  "expo-build-properties",
  {
    ios: {
      useFrameworks: "static",
      buildReactNativeFromSource: true,
    },
  },
]

Verified by using expo 54.0.0-preview.10 and react-native 0.81.1. A better solution is being worked on by expo.

https://github.com/expo/expo/issues/39233 mentioned above is reported by @vonovak as fixing this via https://github.com/expo/expo/pull/39479 by @chrfalch, which is available in the lastest releases, but doesn't fix things for me; possibly there is some configuration needed?

However @chrfalch also has https://github.com/expo/expo/pull/39742 which has landed and that, along with forceStaticLinking: ['RNFBApp'], in expo-build-properties ios gets things building for me (we're only using @react-native-firebase/app and @react-native-firebase/analytics, more config might be needed for others).

Config snippet

    [
      'expo-build-properties',
      {
        ios: {
          useFrameworks: 'static',
          forceStaticLinking: ['RNFBApp'],
        },
      },
    ],

Thanks @chrfalch for your work on this!

elyobo avatar Sep 18 '25 22:09 elyobo