The Play Data safety form, and why RN apps declare it wrong
The Data safety form is a statement about your whole app, including every SDK in it — and in a React Native project you did not choose most of those SDKs. Google's guidance is explicit that your declaration must reflect what the app actually does, libraries included. You are answerable for data practices of code you shipped but did not write.
The common failure is not dishonesty. It is that a developer fills in the form from memory — "we collect an email address and that's it" — while Firebase Analytics is collecting device and usage signals, Crashlytics is collecting diagnostics and device identifiers, a push SDK is collecting a token tied to a device, and an attribution SDK is collecting an advertising ID.
Derive the form from the dependency tree, not from recall. That is a mechanical process, and it is the only version of this that is reliably correct.
What the form actually asks
For each data type, you declare:
- Collected — does it leave the device?
- Shared — is it transferred to a third party?
- Purpose — app functionality, analytics, personalisation, advertising, fraud prevention, and so on
- Optional or required — can the user use the app without providing it?
- Ephemeral — processed transiently and not retained?
- Plus app-level answers on encryption in transit, deletion requests, and whether the app has been independently reviewed against a security standard.
Two of these trip people up regularly. "Shared" does not mean "sold" — sending data to a third-party processor generally counts as a transfer that must be declared. And "collected" turns on whether the data leaves the device, not on whether a human at your company ever looks at it.
The RN dependency map
| Package | What it typically collects | Data-safety rows it usually touches |
|---|---|---|
@react-native-firebase/analytics | App interactions, device and OS info, pseudonymous identifiers | App activity; Device or other IDs |
@react-native-firebase/crashlytics | Crash traces, device state, diagnostic identifiers | App info and performance; Device or other IDs |
@react-native-firebase/messaging | Push tokens tied to an install | Device or other IDs |
@react-native-firebase/auth | Email, phone, provider identifiers | Personal info |
@react-native-google-signin/google-signin | Name, email, profile photo, account ID | Personal info |
react-native-fbsdk-next | Advertising and attribution signals, app events | Device or other IDs; App activity |
react-native-onesignal | Push token, device and locale, engagement events | Device or other IDs; App activity |
| Attribution SDKs (AppsFlyer, Adjust, Branch and similar) | Advertising ID, install referrer, device fingerprinting signals | Device or other IDs |
@react-native-community/geolocation, expo-location | Precise or approximate location | Location |
expo-camera, react-native-image-picker | Photos and video the user selects or captures | Photos and videos |
@react-native-async-storage/async-storage | Nothing off-device by itself | None — unless you sync what you store |
| RevenueCat, Purchases | Purchase history, app user ID, device info | Purchases; Device or other IDs |
| Sentry, Bugsnag | Errors, breadcrumbs, device info, sometimes user ID | App info and performance |
This table is a starting point, not a substitute for reading each vendor's own documentation. Vendors change what they collect between versions, and your declaration has to describe the version you shipped.
The derivation, step by step
- List what is actually in the build, not what is in
package.json. Native dependencies are the ones that matter, and transitive ones count.
grep -E '"(react-native|@react-native|expo)[^"]*"' package.json | sort
./gradlew :app:dependencies --configuration releaseRuntimeClasspath | grep -E '^[+\\]' | sort -u- Read the merged manifest, which is where the permissions your dependencies added actually appear:
find android -name AndroidManifest.xml -path '*merged*' -o -name 'AndroidManifest.xml' -path '*build/intermediates*'Every dangerous permission in there needs either a Data safety row or a reason it does not collect.
- Read each vendor's data-collection page for the version you ship, and note the data types.
- Reconcile row by row. Anything a vendor documents collecting must appear or be justified as not collected in your configuration — and if you disabled a collection feature, be sure it is actually disabled in the release build rather than in a local config.
- Answer the app-level questions honestly. If you offer account creation, you almost certainly need a deletion path — Play requires developers whose apps allow account creation to provide a way to request account and data deletion, including a web-accessible route.
Where this intersects Apple
Play's Data safety form and Apple's Privacy Nutrition Labels ask overlapping questions with different vocabularies and thresholds. A team that fills one in carefully and copies it to the other usually gets both slightly wrong.
Doing the derivation once, from the dependency tree, and then mapping it to both is the only approach that does not drift. It is also, mechanically, what a static tool should do for you: read the manifest and the lockfile, list the SDKs, and flag rows that look inconsistent with what is in the build.
shipcheck runs that reconciliation locally as part of its Play checks — no account, no repository upload, inside the Claude Code session you already have open. What it checks.
Google's policies change frequently. Every claim on this page links to Google's own documentation. Read the source before you submit; a Data safety declaration is a compliance statement, not a marketing field.
Questions and answers
What is the Google Play Data safety section?
A required declaration in Play Console describing what data your app collects and shares, why, whether it is encrypted in transit, and whether users can request deletion. It is displayed on your store listing and Google expects it to be accurate and complete, including data handled by third-party SDKs in your app.
Do I have to declare data collected by third-party SDKs?
Yes. Google's guidance is that your declaration must cover your app's full behaviour including libraries and SDKs it uses. You are responsible for the data practices of code you ship, whether or not you wrote it.
What happens if my Data safety form is wrong?
Google can reject the update, require you to correct the declaration, and in serious or repeated cases take enforcement action against the app or the developer account. An inaccurate declaration is treated as a policy violation rather than a paperwork error.
Which React Native SDKs most often break a Data safety declaration?
Analytics and crash reporting such as Firebase Analytics and Crashlytics, advertising and attribution SDKs, push providers such as OneSignal and Firebase Messaging, and anything collecting device identifiers. All of these collect data that must appear in the declaration even if you never look at it.
How do I check my Data safety form against my app?
Derive it from evidence rather than memory. List the SDKs actually in your build, read each vendor's published data-collection documentation, check the merged AndroidManifest for permissions, and reconcile that against every row in the form.
shipcheck. “The Play Data safety form, and why RN apps declare it wrong.” Baker Ventures LLC, September 6, 2026. https://shipcheck.bakerventuresstudio.com/rejections/play-data-safety-form/