Skip to content

🔥 You need to update react-native-firebase to get new firebase-ios-sdk that complies with App Store Privacy Manifest requirements #7759

Closed
@tfuda

Description

@tfuda

Issue

I have a React Native app that includes a number of react-native-firebase packages (auth, firestore, dynamic-links, etc). I uploaded a new version of my app to App Store Connect and submitted it for review on 4/19/2024. I received the following email:

Hello,

We noticed one or more issues with a recent submission for App Store review for the following app:

MyAppName
Version 1.6.1
Build 72
Although submission for App Store review was successful, you may want to correct the following issues in your next submission for App Store review. Once you've corrected the issues, upload a new binary to App Store Connect.

ITMS-91053: Missing API declaration - Your app’s code in the “MyApp” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryFileTimestamp. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.

ITMS-91053: Missing API declaration - Your app’s code in the “MyApp” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryDiskSpace. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.

ITMS-91053: Missing API declaration - Your app’s code in the “MyApp” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategorySystemBootTime. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.

ITMS-91053: Missing API declaration - Your app’s code in the “MyApp” file references one or more APIs that require reasons, including the following API categories: NSPrivacyAccessedAPICategoryUserDefaults. While no action is required at this time, starting May 1, 2024, when you upload a new app or app update, you must include a NSPrivacyAccessedAPITypes array in your app’s privacy manifest to provide approved reasons for these APIs used by your app’s code. For more details about this policy, including a list of required reason APIs and approved reasons for usage, visit: https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api.

Apple Developer Relations

I believe this message is in response to the fact that my app includes updated versions of react-native-firebase packages that have been identified by Apple as using various APIs that require a privacy manifest that indicates how these libraries uses the data collected via these APIs. Apple identifies a number of Firebase libraries as using APIs that require a privacy manifest here: https://developer.apple.com/support/third-party-SDK-requirements/. I believe this issue will impact many React Native apps that use React Native Firebase libraries to access a Firebase backend on iOS apps.


Project Files

Javascript

Click To Expand

package.json:

{
  "name": "MyAppName",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "start": "react-native start --reset-cache",
    "test": "jest",
    "test:coverage": "jest --coverage",
    "postinstall": "react-native setup-ios-permissions && pod-install && patch-package",
    "bundle:ios": "react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios"
  },
  "dependencies": {
    "@gorhom/bottom-sheet": "^4",
    "@invertase/react-native-apple-authentication": "^2.2.2",
    "@mailchimp/mailchimp_marketing": "^3.0.80",
    "@react-native-community/netinfo": "^9.0.0",
    "@react-native-firebase/analytics": "^18.9.0",
    "@react-native-firebase/app": "^18.9.0",
    "@react-native-firebase/auth": "^18.9.0",
    "@react-native-firebase/crashlytics": "^18.9.0",
    "@react-native-firebase/dynamic-links": "^18.9.0",
    "@react-native-firebase/firestore": "^18.9.0",
    "@react-native-firebase/functions": "^18.9.0",
    "@react-native-firebase/storage": "^18.9.0",
    "@react-native-google-signin/google-signin": "^8.0.0",
    "@react-native-picker/picker": "^2.4.4",
    "@react-native-voice/voice": "^3.2.4",
    "@react-navigation/elements": "^1.3.24",
    "@react-navigation/native": "^6.1.12",
    "@react-navigation/native-stack": "^6.9.20",
    "axios": "^1.6.7",
    "blueimp-md5": "^2.19.0",
    "compromise": "^14.9.0",
    "dayjs": "^1.11.9",
    "geolib": "^3.3.4",
    "querystring": "^0.2.1",
    "react": "18.2.0",
    "react-native": "^0.71.0",
    "react-native-config": "^1.4.6",
    "react-native-date-picker": "^4.2.9",
    "react-native-device-info": "^10.8.0",
    "react-native-dotenv": "^3.3.1",
    "react-native-draggable-flatlist": "^4.0.1",
    "react-native-dropdown-picker": "^5.4.6",
    "react-native-geolocation-service": "^5.3.1",
    "react-native-gesture-handler": "^2.9.0",
    "react-native-gifted-charts": "^1.2.41",
    "react-native-haptic-feedback": "^1.14.0",
    "react-native-image-crop-picker": "^0.40.3",
    "react-native-keyboard-aware-scrollview": "^2.1.0",
    "react-native-linear-gradient": "^2.6.2",
    "react-native-maps": "^1.14.0",
    "react-native-mmkv-storage": "^0.9.1",
    "react-native-pager-view": "^6.2.0",
    "react-native-permissions": "^3.6.1",
    "react-native-picker-select": "^8.0.4",
    "react-native-reanimated": "^3.5.4",
    "react-native-reanimated-carousel": "^3.0.6",
    "react-native-safe-area-context": "^4.9.0",
    "react-native-screens": "^3.29.0",
    "react-native-sound": "^0.11.2",
    "react-native-splash-screen": "^3.3.0",
    "react-native-svg": "^13.7.0",
    "react-native-tab-view": "^3.5.2",
    "react-native-toast-message": "^2.1.5",
    "react-native-tts": "^4.1.0",
    "react-native-wheel-scrollview-picker": "^2.0.4",
    "sp-react-native-in-app-updates": "^1.3.1",
    "string-format": "^2.0.0",
    "use-debounce": "^9.0.2"
  },
  "reactNativePermissionsIOS": [
    "Camera",
    "Microphone",
    "PhotoLibrary",
    "LocationAccuracy",
    "SpeechRecognition",
    "PhotoLibraryAddOnly"
  ],
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native-community/eslint-config": "^3.2.0",
    "@testing-library/react-native": "^12.0.1",
    "@tsconfig/react-native": "^2.0.2",
    "@types/blueimp-md5": "^2.18.0",
    "@types/jest": "^29.2.1",
    "@types/mailchimp__mailchimp_marketing": "^3.0.9",
    "@types/react": "^18.0.24",
    "@types/react-test-renderer": "^18.0.0",
    "@types/string-format": "^2.0.0",
    "@typescript-eslint/eslint-plugin": "^5.37.0",
    "@typescript-eslint/parser": "^5.37.0",
    "babel-jest": "^29.2.1",
    "babel-plugin-module-resolver": "^4.1.0",
    "eslint": "^8.19.0",
    "jest": "^29.2.1",
    "metro-react-native-babel-preset": "^0.73.7",
    "prettier": "^2.8.7",
    "react-native-flipper": "^0.189.0",
    "react-test-renderer": "18.2.0",
    "rn-mmkv-storage-flipper": "^1.1.1",
    "typescript": "^4.8.3"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "testPathIgnorePatterns": [
      "__mocks__"
    ]
  },
  "resolutions": {
    "@types/react": "^17.0.38"
  }
}

firebase.json for react-native-firebase v6:

{
  "react-native": {
    "crashlytics_debug_enabled": true,
    "crashlytics_disable_auto_disabler": true,
    "crashlytics_auto_collection_enabled": true,
    "crashlytics_is_error_generation_on_js_crash_enabled": true,
    "crashlytics_javascript_exception_handler_chaining_enabled": true
  }
}

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '13.4'
prepare_react_native_project!

# 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

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

target 'MyAppName' do
  config = use_native_modules!

  # Flags change depending on the env values.
  flags = get_default_flags()

  rn_maps_path = '../node_modules/react-native-maps'
  pod 'react-native-google-maps', :path => rn_maps_path

  use_react_native!(
    :path => config[:reactNativePath],
    # Hermes is now enabled by default. Disable by setting this flag to false.
    # Upcoming versions of React Native may rely on get_default_flags(), but
    # we make it explicit here to aid in the React Native upgrade process.
    :hermes_enabled => false,
    :fabric_enabled => flags[:fabric_enabled],
    # 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}/.."
  )

  pod 'Firebase', :modular_headers => true
  pod 'FirebaseCore', :modular_headers => true
  pod 'FirebaseCoreInternal', :modular_headers => true
  pod 'GoogleUtilities', :modular_headers => true
  pod 'react-native-config', :path => '../node_modules/react-native-config'
  $RNFirebaseAsStaticFramework = true

  post_install do |installer|
    # installer.pods_project.targets.each do |target|
    #   if target.name == "React-Core.common-AccessibilityResources"
    #     target.remove_from_project
    #   end
    # end

    # Fixes build failure in Xcode 15. See https://github.com/facebook/react-native/issues/37748
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION']
      end
    end

    react_native_post_install(
      installer,
      # Set `mac_catalyst_enabled` to `true` in order to apply patches
      # necessary for Mac Catalyst builds
      :mac_catalyst_enabled => false
    )
    __apply_Xcode_12_5_M1_post_install_workaround(installer)

    installer.pods_project.build_configurations.each do |config|
      config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
    end
  end

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

end

AppDelegate.m:

#import "AppDelegate.h"

#import <React/RCTLinkingManager.h>  // For implementation of deeplinking (visit https://reactnavigation.org/docs/deep-linking/#setup-on-ios for more info)
#import <React/RCTBundleURLProvider.h>

#import <Firebase.h>
#import <RNGoogleSignin/RNGoogleSignin.h>
#import <GoogleMaps/GoogleMaps.h>
#import "RNCConfig.h"
#import "RNSplashScreen.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"MyAppName";
  // 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 = @{};

  NSString *googleApiUrl = [RNCConfig envFor:@"GOOGLE_MAPS_API_KEY"];
  [FIRApp configure];
  [GMSServices provideAPIKey:googleApiUrl];
  bool didFinish = [super application:application didFinishLaunchingWithOptions:launchOptions];
  [RNSplashScreen show];
  return didFinish;
}

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

/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
  return true;
}

// For implementation of deeplinking
- (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];
}

@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:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->


Environment

Click To Expand

react-native info output:

npx react-native info
info Fetching system and libraries information...
System:
    OS: macOS 14.4.1
    CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
    Memory: 497.66 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 19.8.1 - /usr/local/bin/node
    Yarn: 3.6.0 - /usr/local/bin/yarn
    npm: 9.5.1 - /usr/local/bin/npm
    Watchman: 2023.03.27.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.12.0 - /Users/tom/.rbenv/shims/pod
  SDKs:
    iOS SDK:
      Platforms: DriverKit 23.4, iOS 17.4, macOS 14.4, tvOS 17.4, visionOS 1.1, watchOS 10.4
    Android SDK: Not Found
  IDEs:
    Android Studio: 2022.1 AI-221.6008.13.2211.9619390
    Xcode: 15.3/15E204a - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.18 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 18.2.0 => 18.2.0 
    react-native: ^0.71.0 => 0.71.7 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
  • 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:
    • 18.9.0
  • Firebase module(s) you're using that has the issue:
    • analytics, app, auth, crashlytics, dynamic-links, firestore, functions, storage
  • Are you using TypeScript?
    • Y, 4.8.3


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions