invertase / invertase/react-native-google-mobile-ads

[🐛] `NativeAd` paid event type exposes `currencyCode`, but the bridge sends `currency`

Open
#877 1 comment 0 reactions 0 assignees View on GitHub
help wanted stale
Dominant language
TypeScript
Stars
1k
Forks
229
Avg merge
3d 5h
Merged PRs (30d)
7

Description

### What happened?

## Summary

`NativeAd.addAdEventListener(NativeAdEventType.PAID, ...)` exposes a payload type
with `currencyCode`, but both native implementations emit the JavaScript payload
key as `currency`.

TypeScript accepts `payload.currencyCode`, but that property is `undefined` at
runtime. The actual value is available at `payload.currency`.

## Evidence

The NativeAd TypeScript payload declares `currencyCode`:

```ts
export type NativeAdPaidEventPayload = {
value: number;
precision: number;
currencyCode: string;
};
```

https://discord.com/channels/295953187817521152/1059856784308850709/1539547481434492958

### Platforms

Android, but have not tested behavior on iOS

### React Native Info

```Shell
System:
OS: Windows 11 10.0.26200
CPU: "(12) x64 AMD Ryzen 5 5600H with Radeon Graphics "
Memory: 1.60 GB / 15.35 GB
Binaries:
Node:
version: 24.15.0
path: C:\Program Files\nodejs\node.EXE
Yarn:
version: 4.10.3
path: C:\Users\Sanjay Sargam\AppData\Roaming\npm\yarn.CMD
npm:
version: 11.8.0
path: C:\rngma\node_modules\.bin\npm.CMD
Watchman: Not Found
SDKs:
Android SDK:
API Levels:
- "33"
- "34"
- "35"
- "36"
- "36"
- "37"
Build Tools:
- 34.0.0
- 35.0.0
- 36.0.0
- 36.1.0
- 37.0.0
System Images:
- android-33 | Google Play Intel x86_64 Atom
- android-35 | ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-35 | Google Play Intel x86_64 Atom
- android-35 | Google Play Tablet Intel x86_64 Atom
- android-37.0 | 16 KB Page Size Google Play Intel x86_64 Atom
- android-37.1 | 16 KB Page Size Google APIs Intel x86_64 Atom
Android NDK: Not Found
Windows SDK:
AllowDevelopmentWithoutDevLicense: Enabled
IDEs:
Android Studio: AI-261.26222.65.2613.16025427
Visual Studio: Not Found
Languages:
Java:
version: 21.0.10
path: C:\Users\Sanjay Sargam\.jdks\jbr-21.0.10\bin\javac.EXE
Ruby: Not Found
npmPackages:
"@react-native-community/cli":
installed: 20.1.0
wanted: 20.1.0
react:
installed: 19.2.3
wanted: 19.2.3
react-native:
installed: 0.86.0
wanted: 0.86.0
react-native-windows: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: false
newArchEnabled: true
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
```

### Are your using Typescript?

- [x] My project is using Typescript

### package.json

```JSON
{
"name": "RNGoogleMobileAdsExample",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"build:android": "npm run mkdist && react-native bundle --entry-file index.js --platform android --dev true --bundle-output dist/main.android.jsbundle --assets-dest dist/res",
"build:ios": "npm run mkdist && react-native bundle --entry-file index.js --platform ios --dev true --bundle-output dist/main.ios.jsbundle --assets-dest dist",
"ios": "react-native run-ios",
"lint": "eslint .",
"mkdist": "node -e \"require('node:fs').mkdirSync('dist', { recursive: true, mode: 0o755 })\"",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"@react-native/new-app-screen": "0.83.1",
"react": "19.2.3",
"react-native": "0.86.0",
"react-native-google-mobile-ads": "portal:../",
"react-native-safe-area-context": "^5.5.2"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "20.1.0",
"@react-native-community/cli-platform-android": "20.1.0",
"@react-native-community/cli-platform-ios": "20.1.0",
"@react-native/babel-preset": "0.86.0",
"@react-native/eslint-config": "0.86.0",
"@react-native/metro-config": "0.86.0",
"@react-native/typescript-config": "0.86.0",
"@rnx-kit/metro-config": "^2.2.4",
"@types/jest": "^29.5.13",
"@types/react": "^19.1.1",
"@types/react-test-renderer": "^19.1.0",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"jet": "https://github.com/invertase/jet#@mikehardy/jet-next",
"prettier": "2.8.8",
"react-native-test-app": "^5.4.0",
"react-test-renderer": "19.2.3",
"typescript": "^5.8.3"
},
"engines": {
"node": ">= 22.11.0"
}
}
```

### app.json

```JSON
{
"name": "RNGoogleMobileAdsExample",
"displayName": "RNGoogleMobileAdsExample",
"singleApp": "RNGoogleMobileAdsExample",
"components": [
{
"appKey": "RNGoogleMobileAdsExample",
"displayName": "RNGoogleMobileAdsExample",
"slug": "RNGoogleMobileAdsExample"
}
],
"resources": {
"android": [
"dist/res",
"dist/main.android.jsbundle"
],
"ios": [
"dist/assets",
"dist/main.ios.jsbundle"
],
"macos": [
"dist/assets",
"dist/main.macos.jsbundle"
],
"visionos": [
"dist/assets",
"dist/main.visionos.jsbundle"
],
"windows": [
"dist/assets",
"dist/main.windows.bundle"
]
},
"react-native-google-mobile-ads": {
"android_app_id": "ca-app-pub-3940256099942544~3347511713",
"ios_app_id": "ca-app-pub-3940256099942544~1458002511",
"delay_app_measurement_init": false,
"user_tracking_usage_description": "This identifier will be used to deliver personalized ads to you.",
"sk_ad_network_items": [
"cstr6suwn9.skadnetwork",
"4fzdc2evr5.skadnetwork",
"2fnua5tdw4.skadnetwork",
"ydx93a7ass.skadnetwork",
"p78axxw29g.skadnetwork",
"v72qych5uu.skadnetwork",
"ludvb6z3bs.skadnetwork",
"cp8zw746q7.skadnetwork",
"3sh42y64q3.skadnetwork",
"c6k4g5qg8m.skadnetwork",
"s39g8k73mm.skadnetwork",
"wg4vff78zm.skadnetwork",
"3qy4746246.skadnetwork",
"f38h382jlk.skadnetwork",
"hs6bdukanm.skadnetwork",
"mlmmfzh3r3.skadnetwork",
"v4nxqhlyqp.skadnetwork",
"wzmmz9fp6w.skadnetwork",
"su67r6k2v3.skadnetwork",
"yclnxrl5pm.skadnetwork",
"t38b2kh725.skadnetwork",
"7ug5zh24hu.skadnetwork",
"gta9lk7p23.skadnetwork",
"vutu7akeur.skadnetwork",
"y5ghdn5j9k.skadnetwork",
"v9wttpbfk9.skadnetwork",
"n38lu8286q.skadnetwork",
"47vhws6wlr.skadnetwork",
"kbd757ywx3.skadnetwork",
"9t245vhmpl.skadnetwork",
"a2p9lx4jpn.skadnetwork",
"22mmun2rn5.skadnetwork",
"44jx6755aq.skadnetwork",
"k674qkevps.skadnetwork",
"4468km3ulz.skadnetwork",
"2u9pt9hc89.skadnetwork",
"8s468mfl3y.skadnetwork",
"klf5c3l5u5.skadnetwork",
"ppxm28t8ap.skadnetwork",
"kbmxgpxpgc.skadnetwork",
"uw77j35x4d.skadnetwork",
"578prtvx9j.skadnetwork",
"4dzt52r2t5.skadnetwork",
"tl55sbb4fm.skadnetwork",
"c3frkrj4fj.skadnetwork",
"e5fvkxwrpn.skadnetwork",
"8c4e2ghe7u.skadnetwork",
"3rd42ekr43.skadnetwork",
"97r2b46745.skadnetwork",
"3qcr597p9d.skadnetwork"
]
}
}
```

### ios/Podfile

```Ruby

```

### android/build.gradle

```Groovy

```

### android/app/build.gradle

```Groovy

```

### android/settings.gradle

```Groovy

```

### AndroidManifest.xml

```XML

```

Contributor guide

Open the contributing guide

Research direction

Start by searching for NativeAdPaidEventPayload and the NativeAd.addAdEventListener PAID entry point, then trace the Android and iOS bridge emitters that build the event payload. Make the declared and emitted currency property consistent on both platforms, and verify the PAID callback exposes the same value at runtime as the TypeScript type.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, ios, react-native, typescript
Domain
api, mobile
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.