Description
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
- 👉 Check out
React Native Firebase
andInvertase
on Twitter for updates on the library.