12.5 C
New York
Monday, March 17, 2025

Expo 50: firebase + flipper on iOS workarount


Expo 50 has a tough time utilizing concurrently flipper and firebase leading to 404 errors with varied FlipperKit header information, so I publish right here to suggest an answer

The answer is straightforward: disable firebase, and it is possible for you to to make use of Flipper. Nonetheless, there’s a catch.

To begin with, we have to remark use_frameworks within the Podfile:

flipper_config = FlipperConfiguration.disabled
if ENV['NO_FLIPPER'] == '1' then
  # Explicitly disabled via surroundings variables
  flipper_config = FlipperConfiguration.disabled
elsif podfile_properties.key?('ios.flipper') then
  # Configure Flipper in Podfile.properties.json
  if podfile_properties['ios.flipper'] == 'true' then
    flipper_config = FlipperConfiguration.enabled(["Debug", "Release"])
  elsif podfile_properties['ios.flipper'] != 'false' then
    flipper_config = FlipperConfiguration.enabled(["Debug", "Release"], { 'Flipper' => podfile_properties['ios.flipper'] })
  finish
finish

goal 'MyTarget' do
  use_expo_modules!
  config = use_native_modules!

  *#commented to make use of flipper: use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
  #commented to make use of flipper: 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 utility root.
    :app_path => "#{Pod::Config.occasion.installation_root}/..",
    # Word that when you have #commented to make use of flipper: use_frameworks! enabled, Flipper is not going to work if enabled
    :flipper_configuration => flipper_config
  )

and add ios.flipper: "true" to Podfile.properties.json:

{
  "expo.jsEngine": "jsc",
  "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true",
  *"ios.flipper": "true",*
  "ios.useFrameworks": "static"
}

It might be sufficient to make Flipper work, however that is not the case in my undertaking, therefore we’d like pressure firebase to static linking so construct would not fail, for that we add to the Podfile:

pod 'Firebase', :modular_headers => true
pod 'FirebaseCoreInternal', :modular_headers => true
pod 'GoogleUtilities', :modular_headers => true
pod 'FirebaseCore', :modular_headers => true
pod 'FirebaseCoreExtension', :modular_headers => true
pod 'FirebaseInstallations', :modular_headers => true
pod 'GoogleDataTransport', :modular_headers => true
pod 'nanopb', :modular_headers => true

That is it, now construct will not fail and make Flipper work. Nonetheless, it might be not handy to edit Podfile after every prebuild, so I made a plugin use-flipper-plugin.js to automize the method (Word that it modifies Podfile provided that env var FLIPPER is ready to true):

const { withDangerousMod } = require('@expo/config-plugins');
const path = require('path');
const fs = require('fs');

module.exports = operate (config) {
  return withDangerousMod(config, [
    'ios',
    (innerConfig) => {
      if (!process.env.FLIPPER) {
        return innerConfig;
      }

      const manager = new PodfileManager(innerConfig);

      manager.disableFirebase();
      manager.enableFlipper();

      return innerConfig;
    },
  ]);
};

class PodfileManager {
  constructor(config) {
    this._config = config;
  }

  _getPodfile() {
    const podfilePath = path.be part of(
      this._config.modRequest.platformProjectRoot,
      'Podfile'
    );
    return fs.readFileSync(podfilePath, 'utf8');
  }

  _savePodfile(modified) {
    const podfilePath = path.be part of(
      this._config.modRequest.platformProjectRoot,
      'Podfile'
    );
    return fs.writeFileSync(podfilePath, modified, 'utf8');
  }

  _commentUseFrameworks(podfile) {
    return podfile.exchange(
      /(use_frameworks!.+)/gi,
      '#commented to make use of flipper: $1'
    );
  }

  _mockFirebasePods(podfile) {
    const place = podfile.indexOf('use_react_native');
    const pods =
      [
        'Firebase',
        'FirebaseCoreInternal',
        'GoogleUtilities',
        'FirebaseCore',
        'FirebaseCoreExtension',
        'FirebaseInstallations',
        'GoogleDataTransport',
        'nanopb',
      ]
        .map((p) => `  pod '${p}', :modular_headers => true`)
        .be part of('n') + 'nn  ';
    return podfile.slice(0, place - 1) + pods + podfile.slice(place - 1);
  }

  enableFlipper() {
    const propsPath = path.be part of(
      this._config.modRequest.platformProjectRoot,
      'Podfile.properties.json'
    );

    const podProps = JSON.parse(fs.readFileSync(propsPath, 'utf8'));
    podProps['ios.flipper'] = 'true';

    fs.writeFileSync(propsPath, JSON.stringify(podProps, null, 2), 'utf8');
  }

  disableFirebase() {
    const podfile = this._getPodfile();

    let modified = this._mockFirebasePods(podfile);
    modified = this._commentUseFrameworks(modified);

    this._savePodfile(modified);
  }
}

Now you simply want so as to add the plugin to app.json and it will make all modifications:

"plugins": ["./use-flipper-plugin"]

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles