Repository navigation
null properties in maps stripped away on iOS when sent via TurboModules #52802
Description
Description
Hello - I'm a maintainer of React Native Firebase (RNFB). RNFB is currently upgrading its packages to TurboModules, and we found a discrepancy between iOS and android that was not previously an issue with NativeModules.
Here is the reproducer: https://github.com/russellwheatley/null-ios-bug
It's pretty simple; run the app on android/iOS. Press the button that appears, it will send this map to native, native will return the exact data back to the JS side:
{ data: { message: 'Hello, world!', nullType: null } }
android will faithfully return the same map, iOS will strip out the property nullType which you can see in DevTools.
This is a rather big departure from NativeModules and will cause problems for a number of RNFB packages like functions, firestore & real-time database.
This issue has been brought up before:
#49291
reactwg/react-native-releases#785
Let me know if you need any further information.
cc. @mikehardy
Steps to reproduce
- clone repo: https://github.com/russellwheatley/null-ios-bug
- run
cd ReproducerApp. - run
yarn - follow instructions in README to run app: https://github.com/russellwheatley/null-ios-bug#step-1-start-the-metro-server
- press button that appears, and view log in DevTools.
- iOS strips out property
nullTypebecause it hasnullvalue, android does not.
React Native Version
0.80.1
Affected Platforms
Runtime - iOS
Areas
TurboModule - The New Native Module System
Output of npx @react-native-community/cli info
System:
OS: macOS 15.5
CPU: (10) arm64 Apple M1 Max
Memory: 127.64 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.15.0
path: ~/.nvm/versions/node/v22.15.0/bin/node
Yarn:
version: 1.22.22
path: /opt/homebrew/bin/yarn
npm:
version: 10.9.2
path: ~/.nvm/versions/node/v22.15.0/bin/npm
Watchman:
version: 2024.12.02.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.15.2
path: /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 24.5
- iOS 18.5
- macOS 15.5
- tvOS 18.5
- visionOS 2.5
- watchOS 11.5
Android SDK:
API Levels:
- "26"
- "28"
- "29"
- "30"
- "31"
- "32"
- "33"
- "34"
- "35"
Build Tools:
- 28.0.3
- 29.0.2
- 29.0.3
- 30.0.2
- 30.0.3
- 33.0.0
- 33.0.1
- 34.0.0
- 35.0.0
System Images:
- android-28 | Google APIs Intel x86 Atom
- android-28 | Google Play Intel x86 Atom
- android-28 | Google Play Intel x86 Atom_64
- android-29 | Intel x86 Atom_64
- android-29 | Google APIs ARM 64 v8a
- android-30 | Google APIs Intel x86 Atom
- android-30 | Google Play Intel x86 Atom
- android-32 | Google Play ARM 64 v8a
- android-33 | Google APIs ARM 64 v8a
- android-33 | Google APIs Intel x86 Atom_64
- android-33 | Google Play ARM 64 v8a
- android-33 | Google Play Intel x86 Atom_64
- android-TiramisuPrivacySandbox | Google Play Intel x86 Atom_64
Android NDK: 22.1.7171670
IDEs:
Android Studio: 2024.3 AI-243.25659.59.2432.13423653
Xcode:
version: 16.4/16F6
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.7
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli":
installed: 19.0.0
wanted: 19.0.0
react:
installed: 19.1.0
wanted: 19.1.0
react-native:
installed: 0.80.1
wanted: 0.80.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
Android log:
{ data: { message: 'Hello, world!', nullType: null } }
iOS log:
{ data: { message: 'Hello, world!' } }
MANDATORY Reproducer
https://github.com/russellwheatley/null-ios-bug
Screenshots and Videos
No response
Activity
[-]map properties stripped away on iOS when sent via TurboModules[/-][+] `null` properties in maps stripped away on iOS when sent via TurboModules[/+]cipolleschi commentedon Jul 24, 2025
Hi @russellwheatley, thanks for the issue.
This should be fixed in 0.81 with this commit: 4a4fd1c
Do you mind try to create an app with
npx @react-native-community/cli init MyApp --version next --skip-installwhich uses the RC from 0.81.0, and double check whether the problem is fixed?russellwheatley commentedon Jul 25, 2025
Hey @cipolleschi - I copy/pasted the dependencies from running the below command into my repro:
and it was the same result. I even cloned the repo fresh: https://github.com/russellwheatley/null-ios-bug to ensure it wasn't a stale build but it didn't make a difference.
cipolleschi commentedon Jul 31, 2025
@russellwheatley so, the bug was effectively addressed by this PR: #51103
The fix is behind a feature flag, which we turned on but we had to turn off because it was causing a lot of failures internally. People and users might ended up depending on this new behavior and changing it now could be a big breaking change for our users. We need further discussions internally to understand how to roll this out.
One of the benefits of the New Architecture and Codegen is type safety: in general, you should avoid the usage of
unknowntypes and users should always know which are the keys involved. When this is not possible, when the users can specify custom fields, I suggest to use theObjectapproach that will be converted to anNSDictionary. In that way you can iterate over the keys and check for their presence.russellwheatley commentedon Aug 4, 2025
@cipolleschi - could you expand on that, please?
I've tried your method of using
Objectbut it still doesn't have thenullkey here: https://github.com/russellwheatley/null-ios-bug/blob/main/ReproducerApp/ios/NativeFunctionsModule/RCTNativeFunctionsModule.mm#L21To be super clear - I have called
data.data()and looked for thenull(nilkey) which is not present. I'm not sure if this is what you meant when you said "iterate over the keys". See below code snippet:russellwheatley commentedon Sep 2, 2025
@cipolleschi - anything further on this? It's a pretty big problem for RNFB, and we'll have to hack something together to keep parity between android and iOS when we migrate to TurboModules.
react-native-bot commentedon Mar 2, 2026
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
react-native-bot commentedon Mar 2, 2026
This issue is stale because it has been open for 180 days with no activity. It will be closed in 7 days unless you comment on it or remove the "Stale" label.
react-native-bot commentedon Aug 30, 2026
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
react-native-bot commentedon Sep 6, 2026
This issue was closed because it has been stalled for 7 days with no activity.