firebase-ios-sdk: App Store Connect warnings that API usage is not being declared by Firebase

Description

I updated to Firebase 10.22.1, but App Store Connect is still warning of APIs such as mach_absolute_time():

ITMS-91053: Missing API declaration - Your app’s code in the “<app>” 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.

System boot time APIs The following APIs for accessing the system boot time require reasons for use. Use the string NSPrivacyAccessedAPICategorySystemBootTime as the value for the NSPrivacyAccessedAPIType key in your NSPrivacyAccessedAPITypes dictionary. systemUptime mach_absolute_time() In your NSPrivacyAccessedAPITypeReasons array, supply the relevant values from the list below. 35F9.1 Declare this reason to access the system boot time in order to measure the amount of time that has elapsed between events that occurred within the app or to perform calculations to enable timers. Information accessed for this reason, or any derived information, may not be sent off-device. There is an exception for information about the amount of time that has elapsed between events that occurred within the app, which may be sent off-device.

Reproducing the issue

I’m using FirebaseAnalyticsWithoutAdIdSupport and FirebaseCrashlytics

Firebase SDK Version

10.22.1

Xcode Version

15.3

Installation Method

Swift Package Manager

Firebase Product(s)

Analytics, Crashlytics

Targeted Platforms

iOS

Relevant Log Output

No response

If using Swift Package Manager, the project’s Package.resolved

Expand Package.resolved snippet

{
  "pins" : [
    {
      "identity" : "abseil-cpp-binary",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/abseil-cpp-binary.git",
      "state" : {
        "revision" : "df308b8b46607675f2b9ec8e569109008f9155ce",
        "version" : "1.2022062300.1"
      }
    },
    {
      "identity" : "app-check",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/app-check.git",
      "state" : {
        "revision" : "3e464dad87dad2d29bb29a97836789bf0f8f67d2",
        "version" : "10.18.1"
      }
    },
    {
      "identity" : "cocoalumberjack",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/CocoaLumberjack/CocoaLumberjack.git",
      "state" : {
        "revision" : "4b8714a7fb84d42393314ce897127b3939885ec3",
        "version" : "3.8.5"
      }
    },
    {
      "identity" : "collectionconcurrencykit",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
      "state" : {
        "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
        "version" : "0.2.0"
      }
    },
    {
      "identity" : "cryptoswift",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
      "state" : {
        "revision" : "7892a123f7e8d0fe62f9f03728b17bbd4f94df5c",
        "version" : "1.8.1"
      }
    },
    {
      "identity" : "devicekit",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/devicekit/DeviceKit.git",
      "state" : {
        "revision" : "fe41d18eccd92a115cffaa35dfff03018c67e635",
        "version" : "5.2.2"
      }
    },
    {
      "identity" : "firebase-ios-sdk",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/firebase-ios-sdk",
      "state" : {
        "revision" : "be49849dcba96f2b5ee550d4eceb2c0fa27dade4",
        "version" : "10.22.1"
      }
    },
   
    {
      "identity" : "googleappmeasurement",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleAppMeasurement.git",
      "state" : {
        "revision" : "482cfa4e5880f0a29f66ecfd60c5a62af28bd1f0",
        "version" : "10.22.1"
      }
    },
    {
      "identity" : "googledatatransport",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleDataTransport.git",
      "state" : {
        "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565",
        "version" : "9.4.0"
      }
    },
    {
      "identity" : "googleutilities",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/GoogleUtilities.git",
      "state" : {
        "revision" : "26c898aed8bed13b8a63057ee26500abbbcb8d55",
        "version" : "7.13.1"
      }
    },
    {
      "identity" : "grpc-binary",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/grpc-binary.git",
      "state" : {
        "revision" : "ea4cb5cc0c39c732b85386263116d2e2fdbbdc61",
        "version" : "1.49.2"
      }
    },
    {
      "identity" : "gtm-session-fetcher",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/gtm-session-fetcher.git",
      "state" : {
        "revision" : "76135c9f4e1ac85459d5fec61b6f76ac47ab3a4c",
        "version" : "3.3.1"
      }
    },
    {
      "identity" : "interop-ios-for-google-sdks",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/interop-ios-for-google-sdks.git",
      "state" : {
        "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648",
        "version" : "100.0.0"
      }
    },
    {
      "identity" : "leveldb",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/leveldb.git",
      "state" : {
        "revision" : "43aaef65e0c665daadf848761d560e446d350d3d",
        "version" : "1.22.4"
      }
    },
    {
      "identity" : "nanopb",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/firebase/nanopb.git",
      "state" : {
        "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1",
        "version" : "2.30910.0"
      }
    },
    {
      "identity" : "promises",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/google/promises.git",
      "state" : {
        "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac",
        "version" : "2.4.0"
      }
    },
    {
      "identity" : "sourcekitten",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/jpsim/SourceKitten.git",
      "state" : {
        "revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
        "version" : "0.34.1"
      }
    },
    {
      "identity" : "swift-argument-parser",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-argument-parser.git",
      "state" : {
        "revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
        "version" : "1.2.3"
      }
    },
    {
      "identity" : "swift-log",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-log",
      "state" : {
        "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5",
        "version" : "1.5.4"
      }
    },
    {
      "identity" : "swift-protobuf",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-protobuf.git",
      "state" : {
        "revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8",
        "version" : "1.25.2"
      }
    },
    {
      "identity" : "swift-syntax",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/apple/swift-syntax.git",
      "state" : {
        "revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036",
        "version" : "509.0.2"
      }
    },
    {
      "identity" : "swiftlint",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/realm/SwiftLint",
      "state" : {
        "revision" : "f17a4f9dfb6a6afb0408426354e4180daaf49cee",
        "version" : "0.54.0"
      }
    },
    {
      "identity" : "swiftytexttable",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
      "state" : {
        "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
        "version" : "0.9.0"
      }
    },
    {
      "identity" : "swxmlhash",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/drmohundro/SWXMLHash.git",
      "state" : {
        "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
        "version" : "7.0.2"
      }
    },
    {
      "identity" : "yams",
      "kind" : "remoteSourceControl",
      "location" : "https://github.com/jpsim/Yams.git",
      "state" : {
        "revision" : "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3",
        "version" : "5.0.6"
      }
    }
  ],
  "version" : 2
}


If using CocoaPods, the project’s Podfile.lock

Expand Podfile.lock snippet

Replace this line with the contents of your Podfile.lock!

About this issue

  • Original URL
  • State: closed
  • Created 4 months ago
  • Reactions: 74
  • Comments: 73 (20 by maintainers)

Most upvoted comments

Is the issue still on the Firebase side or is it on Apple’s side? I do see there’s a bunch of .bundle files inside the .app, and they have PrivacyInfo.xcprivacy files inside them.

As far as I can tell, it’s entirely on Apple’s side.

The issue:

  • When you use SPM (or CocoaPods if it’s set to use static linking), the code for your dependencies is all placed directly in the main binary for the app. But the corresponding PrivacyInfo.xcprivacy files can’t all be placed directly in the main app bundle without clashing, and there’s no automatic tooling for merging those into a single PrivacyInfo.xcprivacy, so instead a resource bundle (.bundle) for each package is created and nested in the .app, and the PrivacyInfo.xcprivacy file for each package is placed in its corresponding .bundle.

  • This is in contrast with how things are structured when dynamically linked .frameworks are used. In that scenario, the .app binary contains just the top-level app code, and there’s a .framework bundle for each dependency that contains both the binary for its code and its PrivacyInfo.xcprivacy file (along with any other resources).

  • The tooling that Apple is using in its App Store Connect privacy manifest validator seems to only look at the PrivacyInfo.xcprivacy files that are placed directly in the main app bundle or directly in a .framework. It doesn’t actually look at the nested resource bundles created in the static linking case.

So effectively Apple is ignoring the privacy manifests for all dependencies when you use SPM, Apple’s first-party recommended way of managing dependencies. Which is pretty maddening, and makes it seem like the team that created the App Store Connect “required reasons api” validator didn’t actually talk to the people working the privacy manifest support for SPM/Xcode.

Meanwhile, as far as I know, Apple still hasn’t publicly admitted this is the case, or acknowledged if this bug/limitation is something that they intend to address on their end.

If they don’t address it, the only current workaround is to manually create your own top-level PrivacyInfo.xcprivacy files for your apps, and include in them a merging of the contents of the PrivacyInfo.xcprivacy files from your dependencies (in particular the NSPrivacyAccessedAPITypes sections).

But if that’s the expected way of doing things, I think it really undermines the intended purpose of privacy manifests.

Hi @Digipom, thanks for reporting and apologies for the trouble. I was able to reproduce the above behavior. There appears to be an issue with how R.R. API usage attribution is validated when using static frameworks. If you inspect the app bundle, you should see privacy manifests from Firebase that justify this API usage. But since the SDK symbols are statically linked into the main app, the SDK resource bundles do not seem to be taken into account when checking for R.R. API usage.

We have filed a feedback with Apple and I will keep this thread updated.

Is this still being looked into?

Updating to 10.24.0 removed the warning for NSPrivacyAccessedAPICategorySystemBootTime, but we are still getting warnings for NSPrivacyAccessedAPICategoryDiskSpace and NSPrivacyAccessedAPICategoryFileTimestamp.

Unfortunately it isn’t clear from Apple’s messaging if it is coming from Firebase or from another third party library in our project.

@ncooke3 why was this closed?

This issue is still open. They closed a duplicate issue.

EDIT: The number of subscribers on this issue has gotten fairly large so let’s all take extra care to not spam the thread ❤️

@ncooke3 Thank you for your answer. I have a privacy manifest included to my project. In this manifest I declared the reason of using the UserDefaults API. Even if I have this privacy manifest - which is silenced the warning about the userdefaults - I still get warning about NSPrivacyAccessedAPICategorySystemBootTime and NSPrivacyAccessedAPICategoryFileTimestamp which are used by firebase. I would include these to my privacy manifest, but the problem is that I don’t know the exact relevant reasons since I don’t know how firebase uses these APIs exactly…

Hi all, even with 10.24.0 is have the same issue

Thanks, @adrianvintu, that is the behavior I’m seeing. I was also able to reproduce when depending on SwiftPM targets from source. We have filed two feedback tickets with Apple for this (they aren’t publicly visible but are FB13691093 & FB13687188). I don’t yet have a response to share, but will update accordingly!

I think there’s an issue with GoogleUtilities not having a privacy manifest for each target: https://github.com/google/GoogleUtilities/issues/150

(Relevant post from Apple Engineer: https://forums.developer.apple.com/forums/thread/742221?answerId=776008022#776008022)

Hi, I’m experiencing the similar issue, having a warning from Apple regarding NSPrivacyAccessedAPICategoryDiskSpace

I’ve looked through Privacy manifest included with Firebase SDK 10.24.0, and I couldn’t find any declaration of using these APIs

Knowing there is a feature in Crashlytics backend that shows available space on the device during the crash, I assume that issue is on Firebase side of using disk space API calls without declaring them in Privacy manifest. If I’m correct, hope it could be addresses in the next releases.

PS: we are using dynamic linking with cocoapods

Hi,

Do you know if these new privacy declarations mean that apps would have to explicitly ask for permission to report crashes via Firebase Crashlytics?

For reference NSPrivacyAccessedAPICategorySystemBootTime

3D61.1 Declare this reason to include system boot time information in an optional bug report that the person using the device chooses to submit. The system boot time information must be prominently displayed to the person as part of the report.

Information accessed for this reason, or any derived information, may be sent off-device only after the user affirmatively chooses to submit the specific bug report including system boot time information, and only for the purpose of investigating or responding to the bug report.

I’ve installed Firebase 10.23.0 for iOS via CocoaPods. When I search in my Xcode project for the mentioned privacy reason “3D61.1” in your article, I get no matches. However, I do get a match for another reason for NSPrivacyAccessedAPICategorySystemBootTime; “35F9.1”:

Declare this reason to access the system boot time in order to measure the amount of time that has elapsed between events that occurred within the app or to perform calculations to enable timers. Information accessed for this reason, or any derived information, may not be sent off-device. There is an exception for information about the amount of time that has elapsed between events that occurred within the app, which may be sent off-device.

This reason does not demand user permission by Apple.

I did verify all other reasons and they all do comply. Google has even removed collecting Disk Space (which was shown at the “Data” tab of a Crashlytics log), so there is no need to report a reason for NSPrivacyAccessedAPICategoryDiskSpace.

Hi,

Do you know if these new privacy declarations mean that apps would have to explicitly ask for permission to report crashes via Firebase Crashlytics?

For reference NSPrivacyAccessedAPICategorySystemBootTime


3D61.1 Declare this reason to include system boot time information in an optional bug report that the person using the device chooses to submit. The system boot time information must be prominently displayed to the person as part of the report.

Information accessed for this reason, or any derived information, may be sent off-device only after the user affirmatively chooses to submit the specific bug report including system boot time information, and only for the purpose of investigating or responding to the bug report.

Firebase Firestore and GTMSessionFetcher are missing the FileTimeStampAPI key in their XCPrivacy file. They use TimeStamp API’s (stat) and does not declare them. I cannot release my app until these are resolved as our release date is after May 1st.

I’m still getting alerts with 10.23.1.

FIrebaseAnalytics is a statically linked binary.

I use CocoaPods to integrate Crashlytics included in Firebase Apple SDK 10.22.0, and when submitting for review on the App Store, I encountered the same warning as this issue.

I statically link the framework with the following settings in the Podfile.

  use_frameworks! :linkage => :static
  pod 'FirebaseAnalytics'
  pod 'FirebaseCrashlytics'

Although this issue is tagged as Swift Package Manager, is it the same issue that occurred in my environment when using CocoaPods?

I see a lot of apps on the interwebs are using Firebase and Google Maps are complaining about this, mainly that Apple does not merge the privacy codes.

Any news are welcome.

It seems like things are working as intended now, so I believe this has been addressed as of the May 1 deadline. I’m going to close this issue now. Please feel free to open a new issue if anything else comes up.

@nczoltan, yes, that is expected. App Store Connect’s R.R. API validation logic still isn’t processing privacy manifests from frameworks. It only accounts for the privacy manifest in the root of the app, which explains why @Digipom’s approach suppresses the warnings.

Yes. The same issue occurs with CocoaPods when linking statically versus dynamically. As discussed above, as far as we can tell, this is an Apple issue, so it may help to send additional feedback to Apple.

We will at some point, but wanted to preserve the optionality for now, since 1.22.2 is still functional and anyone who cares about the warning can update.

@ncooke3 I’ve been reading Apple’s documentation and think I might have a clue.

I saw you made a new release on the forked leveldb this repo uses that adds the PrivacyInfo file. Firebase does not use this version yet though.

Do you think updating firebase to use leveldb 1.22.4 would solve the issue?

Maybe the warning is still delayed, but I was able to release a new build to TestFlight with 10.25.0 and I didn’t get any warnings. Was there actually an issue on Firebase’s side that was fixed with the move to 10.25.0? Will update in case the warning does come through.

The issue was on App Store Connect’s validation tooling-- it appeared to be ignoring SDK’s privacy manifests for statically linked SDKs. In Firebase 10.25.0, some R.R. API were removed to lessen the surface area that exposed this problem.

I submitted a build on April 30th (it was a patch to the live version that didn’t have any privacy manifests at all) and got it approved and available on the AppStore, and didn’t get any warning email. Paul mentioned here that Apple put some news up on the 26th April that suggests it will only affect new apps and apps that add dependencies on the list after the 1st of May, so it looks like existing apps with existing dependencies are not affected by this change in requirements. (but will be in some future announcement by Apple)

Starting May 1, 2024, new or updated apps that have a newly added third-party SDK that‘s on the list of commonly used third-party SDKs will need …

Maybe the warning is still delayed, but I was able to release a new build to TestFlight with 10.25.0 and I didn’t get any warnings. Was there actually an issue on Firebase’s side that was fixed with the move to 10.25.0? Will update in case the warning does come through.

Hi, I think I have the same problem , using cocoadpods to, even if firebase sdk, crashlytics, messaging and other is up to date I still have the error for NSPrivacyAccessedAPICategoryDiskSpace and NSPrivacyAccessedAPICategorySystemBootTime. I dont know what to do. Did I need to add reason type in my privacy that I think can match the sdk, or is it a bad Idea. Is Apple really gonna block new version for app already in the store may 1st ?

Knowing there is a feature in Crashlytics backend that shows available space on the device during the crash, I assume that issue is on Firebase side of using disk space API calls without declaring them in Privacy manifest. If I’m correct, hope it could be addresses in the next releases.

Hi @fannt & @adrianvintu, Crashlytics’s disk space reporting feature was removed in 10.22.0, so the warning should not be originating from Crashlytics on versions 10.22.0 or later.

@ncooke3 Thank you for your answer. I have a privacy manifest included to my project. In this manifest I declared the reason of using the UserDefaults API. Even if I have this privacy manifest - which is silenced the warning about the userdefaults - I still get warning about NSPrivacyAccessedAPICategorySystemBootTime and NSPrivacyAccessedAPICategoryFileTimestamp which are used by firebase. I would include these to my privacy manifest, but the problem is that I don’t know the exact relevant reasons since I don’t know how firebase uses these APIs exactly…

Easy: just search in the subfolders of your project for PrivacyInfo.xcprivacy file. You will get the privacy infos for severar packages, like firebase and google. See attached sameple firebase ns.txt

Then gather the NS declarations from the different files, and merge them when needed, like below

		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<string>1C8F.1</string>
				<string>C56D.1</string>
			</array>
		</dict>

@adrianvintu, on the right hand side of the first image, no targets are checked for the Target Membership section. I suspect that if you checked the boxes for Runner and Share Extension, the privacy manifest would be included in the app bundle when archiving.

Hi @crleonard, 10.24.0 just finished releasing.

Is there anything I can send you that would be useful to add details to that feedback you filed?

No, I think the ticket I filed is sufficient, but thank you. I’ll continue to keep this bug updated for when I receive an official response on the ticket we have filed.

Correct:

% nm -gU /Users/tomhamming/Library/Developer/Xcode/DerivedData/iOS-dnhixupbtwibvndyouqzyexefztd/Build/Products/Debug-iphonesimulator/BRFree.app/Frameworks/FirebaseCrashlytics.framework/FirebaseCrashlytics /Users/tomhamming/Library/Developer/Xcode/DerivedData/iOS-dnhixupbtwibvndyouqzyexefztd/Build/Products/Debug-iphonesimulator/BRFree.app/Frameworks/FirebaseCrashlytics.framework/FirebaseCrashlytics: no symbols

Which makes it super weird that the binary scanner tool is finding symbols there…

% file ~/Library/Developer/Xcode/DerivedData/iOS-dnhixupbtwibvndyouqzyexefztd/Build/Products/Debug-iphonesimulator/BRFree.app/Frameworks/FirebaseCrashlytics.framework/FirebaseCrashlytics/
/Users/tomhamming/Library/Developer/Xcode/DerivedData/iOS-dnhixupbtwibvndyouqzyexefztd/Build/Products/Debug-iphonesimulator/BRFree.app/Frameworks/FirebaseCrashlytics.framework/FirebaseCrashlytics/: cannot open `/Users/tomhamming/Library/Developer/Xcode/DerivedData/iOS-dnhixupbtwibvndyouqzyexefztd/Build/Products/Debug-iphonesimulator/BRFree.app/Frameworks/FirebaseCrashlytics.framework/FirebaseCrashlytics/' (Not a directory)

If I navigate to that file in Finder, it’s a 35kb file.

Yes. What Xcode are you using?

Xcode 15.3 (15E204a)

After upgrading the Firebase SDK to version 10.23.0, the warning for ‘NSPrivacyAccessedAPICategoryDiskSpace’ is no longer appearing. However, I am still seeing other warnings — ‘NSPrivacyAccessedAPICategoryFileTimestamp’ and ‘NSPrivacyAccessedAPICategoryUserDefaults’. I integrated the Firebase SDK using Swift Package Manager.

This proofs that the implementation of the Privacy files within the Firebase SDK is working as expected. Are you 100% sure that the 2 remaining ones are not related to the code of your own app, or any other 3rd party library?

Our own app also had still 3 warnings remaining. Among themNSPrivacyAccessedAPICategoryUserDefaults, which makes sense since we use NSUserDefaults in our own app. The Apple support page which is referred in the email from App Store Connect, provides sufficient information about functions and methods that you can just search for in your Xcode project. For example for NSPrivacyAccessedAPICategorySystemBootTime it shows systemUptime. When searching for this in our code, we found calls to [[NSProcessInfo processInfo] systemUptime] in our own logic. This means that we are responsible to add a Privacy file ourselves, for example as instructed here. Don’t forget to assign the added Privacy file to the proper target(s).

After submitting the new Build with this Privacy file, we didn’t receive the email from App Store Connect anymore ✅

When we uploaded a build with recent added usage of Firebase Messaging from a notification extension to TestFlight, we got these reported for the extension:

NSPrivacyAccessedAPICategoryFileTimestamp NSPrivacyAccessedAPICategoryUserDefaults

There were no other edits to the notification extension, so what I assume is these are related to FirebaseMessaging, but I couldn’t see them mentioned here.

Same issue here with CocoaPods, I upgraded a few days ago Firebase to 10.23.1 and submitted for review and we still have the same warnings. Will SwiftPM fix also solve the issue when distributing the SDK through CocoaPods?