Skip to content

🔥[🐛] Flaky builds in GitHub Actions #7640

Description

@roryabraham

Issue

We are seeing a number of flaky iOS builds in our CI failing with:

Error: declaration of 'RCTConvert' must be imported from module 'React.RCTConvert' before it is required
      @([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled])]);

Project Files

Javascript

Click To Expand

package.json:

{
  "name": "new.expensify",
  "version": "1.4.43-7",
  "author": "Expensify, Inc.",
  "homepage": "https://new.expensify.com",
  "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
  "license": "MIT",
  "private": true,
  "scripts": {
    "configure-mapbox": "scripts/setup-mapbox-sdk-walkthrough.sh",
    "setupNewDotWebForEmulators": "scripts/setup-newdot-web-emulators.sh",
    "startAndroidEmulator": "scripts/start-android.sh",
    "postinstall": "scripts/postInstall.sh",
    "clean": "npx react-native clean-project-auto",
    "android": "scripts/set-pusher-suffix.sh && npx react-native run-android --mode=developmentDebug --appId=com.expensify.chat.dev",
    "ios": "scripts/set-pusher-suffix.sh && npx react-native run-ios --list-devices --mode=\"DebugDevelopment\" --scheme=\"New Expensify Dev\"",
    "pod-install": "cd ios && bundle exec pod install",
    "ipad": "concurrently \"npx react-native run-ios --simulator=\\\"iPad Pro (12.9-inch) (6th generation)\\\" --mode=\\\"DebugDevelopment\\\" --scheme=\\\"New Expensify Dev\\\"\"",
    "ipad-sm": "concurrently \"npx react-native run-ios --simulator=\\\"iPad Pro (11-inch) (4th generation)\\\" --mode=\\\"DebugDevelopment\\\" --scheme=\\\"New Expensify Dev\\\"\"",
    "start": "npx react-native start",
    "web": "scripts/set-pusher-suffix.sh && concurrently npm:web-proxy npm:web-server",
    "web-proxy": "ts-node web/proxy.js",
    "web-server": "webpack-dev-server --open --config config/webpack/webpack.dev.js",
    "build": "webpack --config config/webpack/webpack.common.js --env envFile=.env.production",
    "build-staging": "webpack --config config/webpack/webpack.common.js --env envFile=.env.staging",
    "build-adhoc": "webpack --config config/webpack/webpack.common.js --env envFile=.env.adhoc",
    "desktop": "scripts/set-pusher-suffix.sh && ts-node desktop/start.js",
    "desktop-build": "scripts/build-desktop.sh production",
    "desktop-build-staging": "scripts/build-desktop.sh staging",
    "createDocsRoutes": "ts-node .github/scripts/createDocsRoutes.js",
    "desktop-build-adhoc": "scripts/build-desktop.sh adhoc",
    "ios-build": "fastlane ios build",
    "android-build": "fastlane android build",
    "android-build-e2e": "bundle exec fastlane android build_e2e",
    "android-build-e2edelta": "bundle exec fastlane android build_e2edelta",
    "test": "TZ=utc jest",
    "typecheck": "tsc",
    "lint": "eslint . --max-warnings=0 --cache --cache-location=node_modules/.cache/eslint",
    "lint-changed": "eslint --fix $(git diff --diff-filter=AM --name-only main -- \"*.js\" \"*.ts\" \"*.tsx\")",
    "lint-watch": "npx eslint-watch --watch --changed",
    "shellcheck": "./scripts/shellCheck.sh",
    "prettier": "prettier --write .",
    "prettier-watch": "onchange \"**/*.{js,ts,tsx}\" -- prettier --write --ignore-unknown {{changed}}",
    "print-version": "echo $npm_package_version",
    "storybook": "start-storybook -p 6006",
    "storybook-build": "ENV=production build-storybook -o dist/docs",
    "storybook-build-staging": "ENV=staging build-storybook -o dist/docs",
    "gh-actions-build": "./.github/scripts/buildActions.sh",
    "gh-actions-validate": "./.github/scripts/validateActionsAndWorkflows.sh",
    "analyze-packages": "ANALYZE_BUNDLE=true webpack --config config/webpack/webpack.common.js --env envFile=.env.production",
    "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map",
    "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map",
    "test:e2e": "ts-node tests/e2e/testRunner.js --development --skipCheckout --skipInstallDeps --buildMode none",
    "test:e2e:dev": "ts-node tests/e2e/testRunner.js --development --skipCheckout --config ./config.dev.js --buildMode skip --skipInstallDeps",
    "gh-actions-unused-styles": "./.github/scripts/findUnusedKeys.sh",
    "workflow-test": "./workflow_tests/scripts/runWorkflowTests.sh",
    "workflow-test:generate": "ts-node workflow_tests/utils/preGenerateTest.js",
    "setup-https": "mkcert -install && mkcert -cert-file config/webpack/certificate.pem -key-file config/webpack/key.pem dev.new.expensify.com localhost 127.0.0.1"
  },
  "dependencies": {
    "@dotlottie/react-player": "^1.6.3",
    "@expensify/react-native-live-markdown": "0.1.5",
    "@expo/metro-runtime": "~3.1.1",
    "@formatjs/intl-datetimeformat": "^6.10.0",
    "@formatjs/intl-getcanonicallocales": "^2.2.0",
    "@formatjs/intl-listformat": "^7.2.2",
    "@formatjs/intl-locale": "^3.3.0",
    "@formatjs/intl-numberformat": "^8.5.0",
    "@formatjs/intl-pluralrules": "^5.2.2",
    "@gorhom/portal": "^1.0.14",
    "@invertase/react-native-apple-authentication": "^2.2.2",
    "@kie/act-js": "^2.6.0",
    "@kie/mock-github": "^1.0.0",
    "@oguzhnatly/react-native-image-manipulator": "github:Expensify/react-native-image-manipulator#5cdae3d4455b03a04c57f50be3863e2fe6c92c52",
    "@onfido/react-native-sdk": "8.3.0",
    "@react-native-async-storage/async-storage": "1.21.0",
    "@react-native-camera-roll/camera-roll": "7.4.0",
    "@react-native-clipboard/clipboard": "^1.13.2",
    "@react-native-community/geolocation": "^3.0.6",
    "@react-native-community/netinfo": "11.2.1",
    "@react-native-firebase/analytics": "^12.3.0",
    "@react-native-firebase/app": "^12.3.0",
    "@react-native-firebase/crashlytics": "^12.3.0",
    "@react-native-firebase/perf": "^12.3.0",
    "@react-native-google-signin/google-signin": "^10.0.1",
    "@react-native-picker/picker": "2.5.1",
    "@react-navigation/material-top-tabs": "^6.6.3",
    "@react-navigation/native": "6.1.8",
    "@react-navigation/stack": "6.3.16",
    "@react-ng/bounds-observer": "^0.2.1",
    "@rnmapbox/maps": "^10.1.11",
    "@shopify/flash-list": "^1.6.3",
    "@ua/react-native-airship": "^15.3.1",
    "@vue/preload-webpack-plugin": "^2.0.0",
    "awesome-phonenumber": "^5.4.0",
    "babel-polyfill": "^6.26.0",
    "canvas-size": "^1.2.6",
    "core-js": "^3.32.0",
    "date-fns": "^2.30.0",
    "date-fns-tz": "^2.0.0",
    "dom-serializer": "^0.2.2",
    "domhandler": "^4.3.0",
    "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#a8ed0f8e1be3a1e09016e07a74cfd13c85bbc167",
    "expo": "^50.0.3",
    "expo-av": "~13.10.4",
    "expo-image": "1.10.1",
    "fbjs": "^3.0.2",
    "htmlparser2": "^7.2.0",
    "idb-keyval": "^6.2.1",
    "jest-expo": "50.0.1",
    "jest-when": "^3.5.2",
    "lodash": "4.17.21",
    "lottie-react-native": "6.4.1",
    "mapbox-gl": "^2.15.0",
    "onfido-sdk-ui": "13.6.1",
    "patch-package": "^8.0.0",
    "process": "^0.11.10",
    "prop-types": "^15.7.2",
    "pusher-js": "8.3.0",
    "react": "18.2.0",
    "react-beautiful-dnd": "^13.1.1",
    "react-collapse": "^5.1.0",
    "react-content-loader": "^6.1.0",
    "react-dom": "18.1.0",
    "react-error-boundary": "^4.0.11",
    "react-map-gl": "^7.1.3",
    "react-native": "0.73.2",
    "react-native-android-location-enabler": "^2.0.1",
    "react-native-blob-util": "0.19.4",
    "react-native-collapsible": "^1.6.1",
    "react-native-config": "^1.4.5",
    "react-native-dev-menu": "^4.1.1",
    "react-native-device-info": "^10.3.0",
    "react-native-document-picker": "^9.1.1",
    "react-native-draggable-flatlist": "^4.0.1",
    "react-native-fs": "^2.20.0",
    "react-native-gesture-handler": "2.14.1",
    "react-native-google-places-autocomplete": "2.5.6",
    "react-native-haptic-feedback": "^2.2.0",
    "react-native-image-pan-zoom": "^2.1.12",
    "react-native-image-picker": "^7.0.3",
    "react-native-image-size": "git+https://github.com/Expensify/react-native-image-size#8393b7e58df6ff65fd41f60aee8ece8822c91e2b",
    "react-native-key-command": "^1.0.6",
    "react-native-launch-arguments": "^4.0.2",
    "react-native-linear-gradient": "^2.8.1",
    "react-native-localize": "^2.2.6",
    "react-native-modal": "^13.0.0",
    "react-native-onyx": "2.0.2",
    "react-native-pager-view": "6.2.2",
    "react-native-pdf": "6.7.3",
    "react-native-performance": "^5.1.0",
    "react-native-permissions": "^3.9.3",
    "react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#da50d2c5c54e268499047f9cc98b8df4196c1ddf",
    "react-native-plaid-link-sdk": "10.8.0",
    "react-native-qrcode-svg": "^6.2.0",
    "react-native-quick-sqlite": "^8.0.0-beta.2",
    "react-native-reanimated": "^3.6.1",
    "react-native-render-html": "6.3.1",
    "react-native-safe-area-context": "4.8.2",
    "react-native-screens": "3.29.0",
    "react-native-sound": "^0.11.2",
    "react-native-svg": "14.1.0",
    "react-native-tab-view": "^3.5.2",
    "react-native-url-polyfill": "^2.0.0",
    "react-native-view-shot": "3.8.0",
    "react-native-vision-camera": "2.16.8",
    "react-native-web": "^0.19.9",
    "react-native-web-linear-gradient": "^1.1.2",
    "react-native-web-sound": "^0.1.3",
    "react-native-webview": "13.6.3",
    "react-pdf": "7.3.3",
    "react-plaid-link": "3.3.2",
    "react-web-config": "^1.0.0",
    "react-webcam": "^7.1.1",
    "react-window": "^1.8.9",
    "save": "^2.4.0",
    "semver": "^7.5.2",
    "shim-keyboard-event-key": "^1.0.3",
    "underscore": "^1.13.1"
  },
  "devDependencies": {
    "@actions/core": "1.10.0",
    "@actions/github": "5.1.1",
    "@babel/core": "^7.20.0",
    "@babel/parser": "^7.22.16",
    "@babel/plugin-proposal-class-properties": "^7.12.1",
    "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
    "@babel/preset-env": "^7.20.0",
    "@babel/preset-flow": "^7.12.13",
    "@babel/preset-react": "^7.10.4",
    "@babel/preset-typescript": "^7.21.5",
    "@babel/runtime": "^7.20.0",
    "@babel/traverse": "^7.22.20",
    "@babel/types": "^7.22.19",
    "@dword-design/eslint-plugin-import-alias": "^4.0.8",
    "@electron/notarize": "^2.1.0",
    "@jest/globals": "^29.5.0",
    "@ngneat/falso": "^7.1.1",
    "@octokit/core": "4.0.4",
    "@octokit/plugin-paginate-rest": "3.1.0",
    "@octokit/plugin-throttling": "4.1.0",
    "@react-native-community/eslint-config": "3.0.0",
    "@react-native/babel-preset": "^0.73.19",
    "@react-native/metro-config": "^0.73.3",
    "@react-navigation/devtools": "^6.0.10",
    "@storybook/addon-a11y": "^6.5.9",
    "@storybook/addon-essentials": "^7.0.0",
    "@storybook/addon-react-native-web": "0.0.19--canary.37.cb55428.0",
    "@storybook/addons": "^6.5.9",
    "@storybook/builder-webpack5": "^6.5.10",
    "@storybook/manager-webpack5": "^6.5.10",
    "@storybook/react": "^6.5.9",
    "@storybook/theming": "^6.5.9",
    "@svgr/webpack": "^6.0.0",
    "@testing-library/jest-native": "5.4.1",
    "@testing-library/react-native": "11.5.1",
    "@trivago/prettier-plugin-sort-imports": "^4.2.0",
    "@types/canvas-size": "^1.2.2",
    "@types/concurrently": "^7.0.0",
    "@types/jest": "^29.5.2",
    "@types/jest-when": "^3.5.2",
    "@types/js-yaml": "^4.0.5",
    "@types/lodash": "^4.14.195",
    "@types/mapbox-gl": "^2.7.13",
    "@types/node": "^20.11.5",
    "@types/pusher-js": "^5.1.0",
    "@types/react": "18.2.45",
    "@types/react-beautiful-dnd": "^13.1.4",
    "@types/react-collapse": "^5.0.1",
    "@types/react-dom": "^18.2.4",
    "@types/react-test-renderer": "^18.0.0",
    "@types/semver": "^7.5.4",
    "@types/setimmediate": "^1.0.2",
    "@types/underscore": "^1.11.5",
    "@typescript-eslint/eslint-plugin": "^6.13.2",
    "@typescript-eslint/parser": "^6.13.2",
    "@vercel/ncc": "0.38.1",
    "@welldone-software/why-did-you-render": "7.0.1",
    "ajv-cli": "^5.0.0",
    "babel-eslint": "^10.1.0",
    "babel-jest": "29.4.1",
    "babel-loader": "^9.1.3",
    "babel-plugin-module-resolver": "^5.0.0",
    "babel-plugin-react-native-web": "^0.18.7",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-remove-console": "^6.9.4",
    "clean-webpack-plugin": "^3.0.0",
    "concurrently": "^5.3.0",
    "copy-webpack-plugin": "^6.4.1",
    "css-loader": "^6.7.2",
    "diff-so-fancy": "^1.3.0",
    "dotenv": "^16.0.3",
    "electron": "^26.6.8",
    "electron-builder": "24.6.4",
    "eslint": "^7.6.0",
    "eslint-config-airbnb-typescript": "^17.1.0",
    "eslint-config-expensify": "^2.0.43",
    "eslint-config-prettier": "^8.8.0",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-jest": "^24.1.0",
    "eslint-plugin-jsdoc": "^46.2.6",
    "eslint-plugin-jsx-a11y": "^6.6.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-native-a11y": "^3.3.0",
    "eslint-plugin-storybook": "^0.5.13",
    "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0",
    "html-webpack-plugin": "^5.5.0",
    "jest": "29.4.1",
    "jest-circus": "29.4.1",
    "jest-cli": "29.4.1",
    "jest-environment-jsdom": "^29.4.1",
    "jest-transformer-svg": "^2.0.1",
    "memfs": "^4.6.0",
    "onchange": "^7.1.0",
    "portfinder": "^1.0.28",
    "prettier": "^2.8.8",
    "pusher-js-mock": "^0.3.3",
    "react-native-clean-project": "^4.0.0-alpha4.0",
    "react-native-performance-flipper-reporter": "^2.0.0",
    "react-test-renderer": "18.2.0",
    "reassure": "^0.10.1",
    "setimmediate": "^1.0.5",
    "shellcheck": "^1.1.0",
    "style-loader": "^2.0.0",
    "time-analytics-webpack-plugin": "^0.1.17",
    "ts-node": "^10.9.2",
    "type-fest": "^3.12.0",
    "typescript": "^5.3.2",
    "wait-port": "^0.2.9",
    "webpack": "^5.76.0",
    "webpack-bundle-analyzer": "^4.5.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3",
    "webpack-merge": "^5.8.0",
    "yaml": "^2.2.1"
  },
  "overrides": {
    "react-native": "$react-native",
    "expo": "$expo",
    "react-native-svg": "$react-native-svg"
  },
  "expo": {
    "autolinking": {
      "exclude": [
        "expo-constants",
        "expo-file-system",
        "expo-font",
        "@react-native-google-signin/google-signin",
        "expo-keep-awake"
      ]
    }
  },
  "electronmon": {
    "patterns": [
      "!node_modules",
      "!node_modules/**/*",
      "!**/*.map",
      "!ios/**",
      "!android/**",
      "*.test.*",
      "*.spec.*"
    ]
  },
  "engines": {
    "node": "20.10.0",
    "npm": "10.2.3"
  }
}

firebase.json for react-native-firebase v6:

{
    "react-native": {
        "crashlytics_disable_auto_disabler": true,
        "crashlytics_debug_enabled": false,
        "crashlytics_ndk_enabled": true
    }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
# Set the type of Mapbox SDK to use
# This value is used by $RNMapboxMaps
$RNMapboxMapsImpl = 'mapbox'

def node_require(script)
  # Resolve script with node to allow for hoisting
  require Pod::Executable.execute_command('node', ['-p',
    "require.resolve(
      '#{script}',
      {paths: [process.argv[1]]},
    )", __dir__]).strip
end

node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')

# Our min supported iOS version is higher than the default (min_ios_version_supported) to support libraires such as Airship
platform :ios, 13.4
prepare_react_native_project!

setup_permissions([
  'Camera',
  'LocationAccuracy',
  'LocationAlways',
  'LocationWhenInUse'
])

# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
#   dependencies: {
#     ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled(['DebugProduction', 'DebugDevelopment', 'DebugAdHoc'])

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
end

# Force pods to match minimum iOS version for React Native
# Fixes build issue on Xcode Cloud where some pods
# Use iOS 12 calls despite being set as iOS 11
def __apply_Xcode_14_3_RC_post_install_workaround(installer)
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      current_target = config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
      minimum_target = min_ios_version_supported
      if current_target.to_f < minimum_target.to_f
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = minimum_target
      end
    end
  end
end

# Configure Mapbox before installing dependencies
pre_install do |installer|
  $RNMapboxMaps.pre_install(installer)
end

target 'NewExpensify' do
  use_expo_modules!
  post_integrate do |installer|
    begin
      expo_patch_react_imports!(installer)
    rescue => e
      Pod::UI.warn e
    end
  end
  permissions_path = '../node_modules/react-native-permissions/ios'

  project 'NewExpensify',
    'DebugDevelopment' => :debug,
    'DebugAdHoc' => :debug,
    'DebugProduction' => :debug,
    'ReleaseDevelopment' => :release,
    'ReleaseAdHoc' => :release,
    'ReleaseProduction' => :release

  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    # Enables Flipper.
    #
    # Note that if you have use_frameworks! enabled, Flipper will not work and
    # you should disable the next line.
    :flipper_configuration => flipper_config,
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )


  target 'NewExpensifyTests' do
    inherit! :complete
    # Pods for testing
  end

  post_install do |installer|
    # Configure Mapbox after installation
    $RNMapboxMaps.post_install(installer)

    # https://github.com/facebook/react-native/blob/main/scripts/react_native_pods.rb#L197-L202
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_14_3_RC_post_install_workaround(installer)

    installer.pods_project.targets.each do |target|
      if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
        target.build_configurations.each do |config|
          config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
        end
      end
    end
  end
end

target 'NotificationServiceExtension' do
  pod 'AirshipServiceExtension'
end

AppDelegate.m:

#import "AppDelegate.h"

#import <Firebase.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTI18nUtil.h>
#import <React/RCTLinkingManager.h>
#import <UserNotifications/UserNotifications.h>

#import "RCTBootSplash.h"
#import "RCTStartupTimer.h"
#import <HardwareShortcuts.h>

@interface AppDelegate () <UNUserNotificationCenterDelegate>

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  self.moduleName = @"NewExpensify";
  // You can add your custom initial props in the dictionary below.
  // They will be passed down to the ViewController used by React Native.
  self.initialProps = @{};
  
  // Configure firebase
  [FIRApp configure];

  // Force the app to LTR mode.
  [[RCTI18nUtil sharedInstance] allowRTL:NO];
  [[RCTI18nUtil sharedInstance] forceRTL:NO];

  [super application:application didFinishLaunchingWithOptions:launchOptions];

  [RCTBootSplash initWithStoryboard:@"BootSplash"
                           rootView:(RCTRootView *)self.window.rootViewController.view]; // <- initialization using the storyboard file name
  
  // Define UNUserNotificationCenter
  UNUserNotificationCenter *center =
      [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self;

  // Start the "js_load" custom performance tracing metric. This timer is
  // stopped by a native module in the JS so we can measure total time starting
  // in the native layer and ending in the JS layer.
  [RCTStartupTimer start];
  
  return YES;
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:
                (NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
  return [RCTLinkingManager application:application
                                openURL:url
                                options:options];
}

- (BOOL)application:(UIApplication *)application
    continueUserActivity:(nonnull NSUserActivity *)userActivity
      restorationHandler:
          (nonnull void (^)(NSArray<id<UIUserActivityRestoring>> *_Nullable))
              restorationHandler {
  return [RCTLinkingManager application:application
                   continueUserActivity:userActivity
                     restorationHandler:restorationHandler];
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
  return [self getBundleURL];
}

- (NSURL *)getBundleURL
{
#if DEBUG
  return
      [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"main"
                                 withExtension:@"jsbundle"];
#endif
}

// This methods is needed to support the hardware keyboard shortcuts
- (NSArray *)keyCommands {
  return [HardwareShortcuts sharedInstance].keyCommands;
}

- (void)handleKeyCommand:(UIKeyCommand *)keyCommand {
  [[HardwareShortcuts sharedInstance] handleKeyCommand:keyCommand];
}

@end


Android

Click To Expand

Have you converted to AndroidX?

  • my application is an AndroidX application?
  • I am using android/gradle.settings jetifier=true for Android compatibility?
  • I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        buildToolsVersion = "34.0.0"
        minSdkVersion = 21
        compileSdkVersion = 34
        targetSdkVersion = 34
        ndkVersion = "25.1.8937393"

        androidXCore = "1.0.2"
        multiDexEnabled = true
        googlePlayServicesVersion = "17.0.0"
        kotlinVersion = '1.8.10'

        // This property configures the type of Mapbox SDK used by the @rnmapbox/maps library.
        // "mapbox" indicates the usage of the Mapbox SDK.
        RNMapboxMapsImpl = "mapbox"
    }
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath("com.android.tools.build:gradle")
        classpath("com.facebook.react:react-native-gradle-plugin")
        classpath("com.google.gms:google-services:4.3.4")
        classpath("com.google.firebase:firebase-crashlytics-gradle:2.7.1")
        classpath("com.google.firebase:perf-plugin:1.4.1")
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
    }
}


allprojects {
    configurations.all {
        resolutionStrategy {
            force 'org.xerial:sqlite-jdbc:3.34.0'

            // Manually set the react-native version to resolve this upstream issue: https://github.com/facebook/react-native/issues/35210
            def REACT_NATIVE_VERSION = new File(['node', '--print',"JSON.parse(require('fs').readFileSync(require.resolve('react-native/package.json'), 'utf-8')).version"].execute(null, rootDir).text.trim())
            force "com.facebook.react:react-native:" + REACT_NATIVE_VERSION
            force "com.facebook.react:hermes-engine:" + REACT_NATIVE_VERSION
        }
    }
    repositories {
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url("$rootDir/../node_modules/react-native/android")
        }
        maven {
            // Mapbox SDK requires authentication to download from Mapbox's private Maven repository.
            url 'https://api.mapbox.com/downloads/v2/releases/maven'
            authentication {
                basic(BasicAuthentication)
            }
            credentials {
                // 'mapbox' is the fixed username for Mapbox's Maven repository.
                username = 'mapbox'

                // The value for password is read from the 'MAPBOX_DOWNLOADS_TOKEN' gradle property. 
                // Run "npm run setup-mapbox-sdk" to set this property in «USER_HOME»/.gradle/gradle.properties

                // Example gradle.properties entry:
                // MAPBOX_DOWNLOADS_TOKEN=YOUR_SECRET_TOKEN_HERE
                password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: ""
            }
        }
    }
}

apply plugin: "com.facebook.react.rootproject"

android/app/build.gradle:

apply plugin: "com.android.application"
apply plugin: "org.jetbrains.kotlin.android"
apply plugin: "com.facebook.react"
apply plugin: "com.google.firebase.firebase-perf"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"

/**
 * This is the configuration block to customize your React Native Android app.
 * By default you don't need to apply any configuration, just uncomment the lines you need.
 */
react {
    /* Folders */
    //   The root of your project, i.e. where "package.json" lives. Default is '..'
    // root = file("../")
    //   The folder where the react-native NPM package is. Default is ../node_modules/react-native
    // reactNativeDir = file("../node_modules/react-native")
    //   The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
    // codegenDir = file("../node_modules/@react-native/codegen")
    //   The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
    // cliFile = file("../node_modules/react-native/cli.js")

    /* Variants */
    //   The list of variants to that are debuggable. For those we're going to
    //   skip the bundling of the JS bundle and the assets. By default is just 'debug'.
    //   If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
    debuggableVariants = ["developmentDebug", "productionDebug"]

    /* Bundling */
    //   A list containing the node command and its flags. Default is just 'node'.
    // nodeExecutableAndArgs = ["node"]
    //
    //   The command to run when bundling. By default is 'bundle'
    // bundleCommand = "ram-bundle"
    //
    //   The path to the CLI configuration file. Default is empty.
    // bundleConfig = file(../rn-cli.config.js)
    //
    //   The name of the generated asset file containing your JS bundle
    // bundleAssetName = "MyApplication.android.bundle"
    //
    //   The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
    // entryFile = file("../js/MyApplication.android.js")
    //
    //   A list of extra flags to pass to the 'bundle' commands.
    //   See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
    // extraPackagerArgs = []

    /* Hermes Commands */
    //   The hermes compiler command to run. By default it is 'hermesc'
    // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
    //
    //   The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
    // hermesFlags = ["-O", "-output-source-map"]
    //
    // Added by install-expo-modules
    entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", rootDir.getAbsoluteFile().getParentFile().getAbsolutePath(), "android", "absolute"].execute(null, rootDir).text.trim())
    cliFile = new File(["node", "--print", "require.resolve('@expo/cli')"].execute(null, rootDir).text.trim())
    bundleCommand = "export:embed"
}

project.ext.envConfigFiles = [
    productionDebug: ".env.production",
    productionRelease: ".env.production",
    adhocRelease: ".env.adhoc",
    developmentRelease: ".env",
    developmentDebug: ".env",
    e2eRelease: "tests/e2e/.env.e2e",
    e2edeltaRelease: "tests/e2e/.env.e2edelta"
]

/**
 * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
 */
def enableProguardInReleaseBuilds = true

/**
 * The preferred build flavor of JavaScriptCore (JSC)
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US. Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc:+'

android {
    ndkVersion rootProject.ext.ndkVersion

    buildToolsVersion rootProject.ext.buildToolsVersion
    compileSdkVersion rootProject.ext.compileSdkVersion

    namespace "com.expensify.chat"
    defaultConfig {
        applicationId "com.expensify.chat"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        multiDexEnabled rootProject.ext.multiDexEnabled
        versionCode 1001044307
        versionName "1.4.43-7"
    }

    flavorDimensions "default"
    productFlavors {
        // we need to define a production flavor but since it has default config, we can leave it empty
        production
        e2e {
            // If  are building a version that won't be uploaded to the play store, we don't have to use production keys
            // applies all non-production flavors
            applicationIdSuffix ".e2e"
            signingConfig signingConfigs.debug
            resValue "string", "build_config_package", "com.expensify.chat"
        }
        e2edelta {
            // If  are building a version that won't be uploaded to the play store, we don't have to use production keys
            // applies all non-production flavors
            applicationIdSuffix ".e2edelta"
            signingConfig signingConfigs.debug
            resValue "string", "build_config_package", "com.expensify.chat"
        }
        adhoc {
            applicationIdSuffix ".adhoc"
            signingConfig signingConfigs.debug
            resValue "string", "build_config_package", "com.expensify.chat"
        }
        development {
            applicationIdSuffix ".dev"
            signingConfig signingConfigs.debug
            resValue "string", "build_config_package", "com.expensify.chat"
        }
    }

    signingConfigs {
        release {
            storeFile file(MYAPP_UPLOAD_STORE_FILE)
            storePassword System.getenv('MYAPP_UPLOAD_STORE_PASSWORD')
            keyAlias MYAPP_UPLOAD_KEY_ALIAS
            keyPassword System.getenv('MYAPP_UPLOAD_KEY_PASSWORD')
        }
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
        }
        release {
            productFlavors.production.signingConfig signingConfigs.release
            shrinkResources enableProguardInReleaseBuilds
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"

            signingConfig null
            // buildTypes take precedence over productFlavors when it comes to the signing configuration,
            // thus we need to manually set the signing config, so that the e2e uses the debug config again.
            // In other words, the signingConfig setting above will be ignored when we build the flavor in release mode. 
            productFlavors.all { flavor ->
                // All release builds should be signed with the release config ...
                flavor.signingConfig signingConfigs.release
            }
            // ... except for the e2e flavor, which we maybe want to build locally:
            productFlavors.e2e.signingConfig signingConfigs.debug
            productFlavors.e2edelta.signingConfig signingConfigs.debug
        }
    }

    // since we don't need variants adhocDebug and e2eDebug, we can force gradle to ignore them
    variantFilter { variant ->
        if (variant.name == "adhocDebug" || variant.name == "e2eDebug" || variant.name == "e2edeltaDebug") {
            setIgnore(true)
        }
    }
}

dependencies {
    // The version of react-native is set by the React Native Gradle Plugin
    implementation("com.facebook.react:react-android")
    implementation("com.facebook.react:flipper-integration")

    if (hermesEnabled.toBoolean()) {
        implementation("com.facebook.react:hermes-android")
    } else {
        implementation jscFlavor
    }

    // Firebase libraries (using the Firebase BoM for consistency - see https://firebase.google.com/docs/android/learn-more#bom)
    implementation platform("com.google.firebase:firebase-bom:29.0.3")
    implementation "com.google.firebase:firebase-perf"
    implementation "com.google.firebase:firebase-crashlytics"

    // GIF support
    implementation 'com.facebook.fresco:fresco:2.5.0'
    implementation 'com.facebook.fresco:animated-gif:2.5.0'

    // Android support library
    implementation 'com.android.support:support-core-utils:28.0.0'

    // Multi Dex Support: https://developer.android.com/studio/build/multidex#mdex-gradle
    implementation 'com.android.support:multidex:1.0.3'

    // Plaid SDK
    implementation project(':react-native-plaid-link-sdk')

    // Fixes a version conflict between airship and react-native-plaid-link-sdk
    // This may be fixed by a newer version of the plaid SDK (not working as of 10.0.0)
    implementation "androidx.work:work-runtime-ktx:2.8.0"

    // This okhttp3 dependency prevents the app from crashing - See https://github.com/plaid/react-native-plaid-link-sdk/issues/74#issuecomment-648435002
    implementation "com.squareup.okhttp3:okhttp-urlconnection:4.+"

    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0")
}

apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply plugin: 'com.google.gms.google-services'  // Google Play services Gradle plugin
apply plugin: 'com.google.firebase.crashlytics'

android/settings.gradle:

rootProject.name = 'NewExpensify'
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-image-size'
project(':react-native-image-size').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-size/android')
include ':react-native-config'
project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android')
include ':react-native-plaid-link-sdk'
project(':react-native-plaid-link-sdk').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-plaid-link-sdk/android')
include ':react-native-dev-menu'
project(':react-native-dev-menu').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-dev-menu/android')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/@react-native/gradle-plugin')

apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
useExpoModules()

MainApplication.java:

package com.expensify.chat

import android.content.res.Configuration
import android.database.CursorWindow
import androidx.multidex.MultiDexApplication
import com.expensify.chat.bootsplash.BootSplashPackage
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactNativeHost
import com.facebook.react.modules.i18nmanager.I18nUtil
import com.facebook.soloader.SoLoader
import com.google.firebase.crashlytics.FirebaseCrashlytics
import expo.modules.ApplicationLifecycleDispatcher
import expo.modules.ReactNativeHostWrapper

class MainApplication : MultiDexApplication(), ReactApplication {
    override val reactNativeHost: ReactNativeHost = ReactNativeHostWrapper(this, object : DefaultReactNativeHost(this) {
        override fun getUseDeveloperSupport() = BuildConfig.DEBUG

        override fun getPackages(): List<ReactPackage>  = 
            PackageList(this).packages.apply {
            // Packages that cannot be autolinked yet can be added manually here, for example:
            // add(MyReactNativePackage());
            add(BootSplashPackage())
            add(ExpensifyAppPackage())
            add(RNTextInputResetPackage())
        }

        override fun getJSMainModuleName() = ".expo/.virtual-metro-entry"

        override val isNewArchEnabled: Boolean
            get() = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
        override val isHermesEnabled: Boolean
            get() = BuildConfig.IS_HERMES_ENABLED
    })

    override fun onCreate() {
        super.onCreate()

        SoLoader.init(this,  /* native exopackage */false)
        if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
            // If you opted-in for the New Architecture, we load the native entry point for this app.
            load()
        }
        if (BuildConfig.DEBUG) {
            FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(false)
        }

        // Force the app to LTR mode.
        val sharedI18nUtilInstance = I18nUtil.getInstance()
        sharedI18nUtilInstance.allowRTL(applicationContext, false)

        // Start the "js_load" custom performance tracing metric. This timer is stopped by a native
        // module in the JS so we can measure total time starting in the native layer and ending in
        // the JS layer.
        StartupTimer.start()

        // Increase SQLite DB write size
        try {
            val field = CursorWindow::class.java.getDeclaredField("sCursorWindowSize")
            field.isAccessible = true
            field[null] = 100 * 1024 * 1024 //the 100MB is the new size
        } catch (e: Exception) {
            e.printStackTrace()
        }
        ApplicationLifecycleDispatcher.onApplicationCreate(this);
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
    }
}

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.expensify.chat">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>

    <!-- android:hardwareAccelerated is essential for Android performance: https://developer.android.com/topic/performance/hardware-accel -->
    <application
        android:name=".MainApplication"
        android:allowBackup="false"
        android:hardwareAccelerated="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:resizeableActivity="false"
        android:supportsRtl="false"
        android:theme="@style/AppTheme"
        tools:replace="android:supportsRtl">

        <activity
            android:name=".MainActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
            android:exported="true"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:theme="@style/BootTheme"
            android:windowSoftInputMode="adjustResize">

            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <!-- Custom URI handlers. Used to intercept Urban Airship deep links. -->
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="new-expensify" />
            </intent-filter>

            <!-- Web URL handlers. Used to intercept web links. -->
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <!-- Production URLs -->
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/r"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/a"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/settings"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/details"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/v"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/bank-account"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/iou"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/request"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/enable-payments"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/statements"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/concierge"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/split"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/request"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/new"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/search"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/send"/>
                <data android:scheme="https" android:host="new.expensify.com" android:pathPrefix="/money2020"/>

                <!-- Staging URLs -->
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/r"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/a"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/settings"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/details"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/v"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/bank-account"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/iou"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/request"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/enable-payments"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/statements"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/concierge"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/split"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/request"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/new"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/search"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/send"/>
                <data android:scheme="https" android:host="staging.new.expensify.com" android:pathPrefix="/money2020"/>
            </intent-filter>
        </activity>

        <meta-data
            android:name="com.urbanairship.reactnative.AIRSHIP_EXTENDER"
            android:value="com.expensify.chat.customairshipextender.CustomAirshipExtender" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/ic_launcher" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/bootsplash_background" />

    </application>
</manifest>


Environment

Click To Expand

react-native info output:

info Fetching system and libraries information...
System:
  OS: macOS 14.3.1
  CPU: (12) arm64 Apple M2 Max
  Memory: 4.37 GB / 96.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.10.0
    path: ~/.nvm/versions/node/v20.10.0/bin/node
  Yarn: Not Found
  npm:
    version: 10.2.3
    path: ~/.nvm/versions/node/v20.10.0/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.12.1
    path: /Users/roryabraham/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 23.0
      - iOS 17.0
      - macOS 14.0
      - tvOS 17.0
      - visionOS 1.0
      - watchOS 10.0
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: 15.1/15C5028h
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.9
    path: /Users/roryabraham/.jenv/shims/javac
  Ruby:
    version: 2.7.5
    path: /Users/roryabraham/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.2
    wanted: 0.73.2
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

info React Native v0.73.4 is now available (your project is running on v0.73.2).
info Changelog: https://github.com/facebook/react-native/releases/tag/v0.73.4
info Diff: https://react-native-community.github.io/upgrade-helper/?from=0.73.4
info For more info, check out "https://reactnative.dev/docs/upgrading?os=macos".
  • Platform that you're experiencing the issue on:
    • 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:
    • 12.3.0
  • Firebase module(s) you're using that has the issue:
    • Crashlytics
  • Are you using TypeScript?
    • Y, 5.3.2


Metadata

Metadata

Assignees

No one assigned

    Labels

    help: needs-triageIssue needs additional investigation/triaging.type: bugNew bug report

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions