invertase / react-native-firebase

šŸ”„ A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.69k stars 2.21k forks source link

Apple rejects app because of AppTrackingTransparency.framework šŸ”„šŸ”„ #5064

Closed ilyakar closed 3 years ago

ilyakar commented 3 years ago

Issue

Just got this message from Apple this morning:

We noticed that your Kids Category app includes analytics, advertising and collects, transmits, or has the ability to share personal information or device information with third parties. Specifically:

- Your app implements the App Tracking Transparency framework, which is used when apps collect data about users and share it with third-parties for tracking purposes. Since Kids Category apps are not allowed to collect, transmit or share identifiable information with third-parties, you should not implement App Tracking Transparency in your app.

Nowhere in our app is the framework included. So my only thought is that somehow Firebase is adding the framework. Is this possible? If so, how can I use the analytics without including the AppTrackingTransparency.framework so that Apple doesn't reject our app?


Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "name": "Einee", "version": "1.8.45", "private": true, "husky": { "hooks": { "post-merge": "if git-branch-is beta -q || git-branch-is master -q; then yarn version --patch; fi" } }, "scripts": { "start": "react-native start", "ios": "react-native run-ios --device", "run:ios:8": "react-native run-ios --simulator=\"iPhone 8\"", "run:ios:iPad": "react-native run-ios --simulator=\"iPad Pro (12.9-inch) (3rd generation)\"", "lint:fix": "eslint --fix --ext .js,.jsx,.ts,.tsx ./", "postversion": "react-native-version --reset-build", "patch-version": "yarn version --patch" }, "jest": { "preset": "react-native" }, "dependencies": { "@react-native-async-storage/async-storage": "^1.13.2", "@react-native-community/async-storage": "^1.7.1", "@react-native-community/blur": "^3.4.1", "@react-native-community/masked-view": "^0.1.6", "@react-native-community/picker": "^1.8.1", "@react-native-firebase/analytics": "10.5.1", "@react-native-firebase/app": "10.5.0", "@react-native-firebase/crashlytics": "10.5.1", "@terrysahaidak/react-native-devmenu": "^3.0.0", "add": "^2.0.6", "amplitude-js": "^7.3.0", "lodash": "^4.17.4", "moment": "^2.22.2", "react": "16.13.1", "react-native": "0.63.4", "react-native-config": "^1.3.3", "react-native-dev-menu": "^4.0.0", "react-native-device-info": "^8.0.1", "react-native-emoji": "^1.8.0", "react-native-fast-image": "^8.3.2", "react-native-fs": "^2.16.6", "react-native-gesture-handler": "^1.5.6", "react-native-haptic-feedback": "^1.9.0", "react-native-iap": "5.2.3", "react-native-loading-spinner-overlay": "^2.0.0", "react-native-mail": "^6.0.0", "react-native-media-queries": "^0.3.0", "react-native-onesignal": "^4.0.3", "react-native-picker-select": "^8.0.2", "react-native-rate": "^1.1.10", "react-native-reanimated": "^1.7.0", "react-native-restart": "^0.0.20", "react-native-safe-area-context": "^3.1.8", "react-native-screens": "^2.0.0-alpha.33", "react-native-share": "^5.1.0", "react-native-sound": "^0.11.0", "react-native-swiper": "^1.6.0", "react-native-tts": "^3.2.0", "react-native-vector-icons": "^8.0.0", "react-navigation": "^4.1.0", "react-navigation-stack": "^2.1.0", "react-redux": "^7.1.3", "redux": "^4.0.5", "redux-action-listeners": "^1.0.2", "redux-thunk": "^2.2.0", "rn-fetch-blob": "^0.12.0", "styled-components": "^5.1.1" }, "devDependencies": { "@babel/core": "^7.8.4", "@babel/runtime": "^7.8.4", "@react-native-community/eslint-config": "^2.0.0", "@types/lodash": "^4.14.165", "@types/react": "^17.0.0", "@types/react-native": "^0.63.37", "@types/react-navigation": "^3.4.0", "@types/react-redux": "^7.1.11", "@typescript-eslint/eslint-plugin": "^4.14.1", "@typescript-eslint/parser": "^4.14.1", "babel-jest": "^26.6.3", "babel-plugin-module-resolver": "^4.0.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", "enzyme-to-json": "^3.3.5", "eslint": "^7.18.0", "eslint-config-airbnb-typescript": "^12.0.0", "eslint-config-prettier": "^7.2.0", "eslint-import-resolver-typescript": "^2.3.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.22.0", "git-branch-is": "^4.0.0", "husky": "4.3.8", "jest": "^26.6.3", "jest-environment-enzyme": "^7.0.2", "jest-enzyme": "^7.0.2", "metro-react-native-babel-preset": "^0.64.0", "pre-push": "^0.1.1", "prettier": "^2.2.1", "react-dom": "^17.0.1", "react-native-debugger-open": "^0.3.25", "react-native-version": "^4.0.0", "react-test-renderer": "17.0.1", "redux-mock-store": "^1.5.3", "typescript": "4.0.5" } } ``` #### `firebase.json` for react-native-firebase v6: ```json # N/A ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' platform :ios, '10.0' target 'Einee' do config = use_native_modules! use_react_native!(:path => config["reactNativePath"]) target 'EineeTests' do inherit! :complete # Pods for testing end # Enables Flipper. # # Note that if you have use_frameworks! enabled, Flipper will not work and # you should disable these next few lines. use_flipper! post_install do |installer| flipper_post_install(installer) end end target 'OneSignalNotificationServiceExtension' do pod 'OneSignal', '>= 3.0', '< 4.0' end target 'Einee-tvOS' do # Pods for Einee-tvOS target 'Einee-tvOSTests' do inherit! :search_paths # Pods for testing end end ``` #### `AppDelegate.m`: ```objc #import #import "AppDelegate.h" #import #import #import #ifdef FB_SONARKIT_ENABLED #import #import #import #import #import #import static void InitializeFlipper(UIApplication *application) { FlipperClient *client = [FlipperClient sharedClient]; SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; [client addPlugin:[FlipperKitReactPlugin new]]; [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; [client start]; } #endif @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { #ifdef FB_SONARKIT_ENABLED InitializeFlipper(application); #endif if ([FIRApp defaultApp] == nil) { [FIRApp configure]; } RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"Einee" initialProperties:nil]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; return YES; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } @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`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 10.15.7 CPU: (8) x64 Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz Memory: 4.25 GB / 16.00 GB Shell: 5.7.1 - /bin/zsh Binaries: Node: 12.18.3 - /usr/local/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 6.14.6 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.1 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2 Android SDK: Not Found IDEs: Android Studio: Not Found Xcode: 12.4/12D4e - /usr/bin/xcodebuild Languages: Java: 1.8.0_121 - /usr/bin/javac Python: 3.9.1 - /usr/local/opt/python/libexec/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.13.1 => 16.13.1 react-native: 0.63.4 => 0.63.4 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **Platform that you're experiencing the issue on**: - [x] iOS - [ ] Android - [x] **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:** - 10.5.0 - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y/N` & `VERSION`


mikehardy commented 3 years ago

Hi there! This (apps using analytics while in kids category) is an area of ongoing development, you have to stay completely up to date:

These specifically are old:

    "@react-native-firebase/analytics": "10.5.1",
    "@react-native-firebase/app": "10.5.0",
    "@react-native-firebase/crashlytics": "10.5.1",

...and unless you override the firebase-ios-sdk version (which you are not doing in the Podfile) to 7.8.1 or more I think this will happen: https://firebase.google.com/support/release-notes/ios#analytics_1

react-native-firebase v11.1.1 and higher will pull in that version of firebase-ios-sdk then it should work? https://github.com/invertase/react-native-firebase/blob/master/CHANGELOG.md#1111-2021-03-16

mikehardy commented 3 years ago

I just dug in a bit more and it appears firebase-ios-sdk 7.8.1 with analytics may still be problematic: https://github.com/firebase/firebase-ios-sdk/issues/7736 - I apologize for the inconvenience but please understand that as react-native-firebase is just wrapping the underlying firebase-ios-sdk we are powerless here. The workaround appears to be to temporarily remove the analytics / measurement frameworks (as indicated in the issue I link in this comment) - I would definitely follow that issue for updates

ilyakar commented 3 years ago

Thanks @mikehardy for looking into this! :)

Okay, for now I'll just remove firebase analytics from the app and look into adding it back in a few months. So, just to confirm, it's just the analytics that's causing the issue? I can leave @react-native-firebase/app and @react-native-firebase/crashlytics in?

mikehardy commented 3 years ago

@ilyakar that sounds right - there is reported success on the linked issue getting Kids category apps approved by Apple when not including Analytics. Definitely subscribe to that issue (little button on right side of GitHub Web UI) in order to see when it's fixed (and what firebase-ios-sdk version), then follow along on our releases page to find out when we adopt that SDK version (or, actually, you can override it to test if you like, like so https://rnfirebase.io/#overriding-native-sdk-versions)

Since there is nothing actionable for us I'm going to close this but I understand it is an ongoing problem, it is something I'm tracking personally as it is obviously an area that affects people - we are paying attention just nothing we can do

ilyakar commented 3 years ago

Thanks so much Mike! Will do.

kenMarquez commented 3 years ago

The Firebase team worked on a beta version, where all references from App Tracking Trasnparency are removed

https://github.com/firebase/firebase-ios-sdk/issues/7736#issuecomment-811340570

image

mikehardy commented 3 years ago

Fantastic thanks for posting that. The advice in that post should work even if you are using Analytics via @react-natve-frebase/analytics though you want to specify it a little differently I think?

In your Podfile add this (or maybe '-k2':

$FirebaseSDKVersion = '7.9.0-k1' # https://firebase.google.com/support/release-notes/ios

...then the Podfile.lock should have the '-k2' suffixes I believe

I would love to hear if anyone tries that for react-native-firebase as well, I'm not near a computer that can build it at the moment

curiousdustin commented 3 years ago

I can confirm that an update to one of my apps was rejected by Apple with this same message:

We noticed that your Kids Category app includes analytics, advertising and collects, transmits, or has the ability to share personal information or device information with third parties. Specifically:

- Your app implements the App Tracking Transparency framework, which is used when apps collect data about users and share it with third-parties for tracking purposes. Since Kids Category apps are not allowed to collect, transmit or share identifiable information with third-parties, you should not implement App Tracking Transparency in your app.

I added the following line as suggested at the top of my Podfile:

$FirebaseSDKVersion = '7.9.0-k2'

I resubmitted with this as the only change, and was approved by Apple.

Thanks @mikehardy, @kenMarquez, and everyone else! šŸŽ‰

mikehardy commented 3 years ago

There has been more development in this area, and I believe the combo of firebase-ios-sdk 7.11.0 (which added a cocoapods subspec to Analytics with no AdIds) in combo with the support I added for the same in react-native-firebase v11.4.x may be the final solution: https://github.com/invertase/react-native-firebase/blob/master/CHANGELOG.md#1141-2021-04-29