This is an Expo example app for testing react-native-iap with the bundle identifier dev.hyo.martie.
This example app is NOT part of the yarn workspace and is managed independently.
After extensive testing, we discovered that Expo's autolinking system has fundamental conflicts with yarn workspaces when developing native modules:
- Plugin Conflict: Expo autolinking attempts to apply both
com.android.libraryandcom.android.applicationplugins to the same project, causing build failures - Workspace Detection: Expo autolinking incorrectly detects the parent library in a workspace structure and processes it as a nested module
- Persistent Error: The error consistently occurs at line 333 of
expo-modules-autolinking/scripts/android/autolinking_implementation.gradle
These issues make it impossible to use Expo apps within yarn workspaces for native module development, hence this independent setup.
- This project uses bun for faster package management (independent from the root yarn workspace)
- The
react-native-iaplibrary is linked via a custom postinstall script
The postinstall script (scripts/postinstall.sh) automatically sets up the development environment:
-
Creates Symlinks for live development:
src/→ TypeScript source code (editable in root)ios/→ iOS native codeandroid/→ Android native codeplugin/→ Expo plugin code
-
Copies Essential Files:
package.json,README.md,tsconfig.json
-
Builds the Library:
- Runs
yarn preparein root directory - Copies compiled files (
lib/,nitrogen/)
- Runs
This allows you to:
- ✅ Edit TypeScript files directly in
../src/ - ✅ See changes immediately reflected in the example app
- ✅ Test native code modifications without republishing
- Bundle Identifier (iOS):
dev.hyo.martie - Package Name (Android):
dev.hyo.martie - App Name: Martie IAP Example
- iOS: The app must be configured in App Store Connect with the bundle ID
dev.hyo.martie - Android: The app must be configured in Google Play Console with the package name
dev.hyo.martie - Products: In-app purchase products must be created with IDs matching those in the app:
dev.hyo.martie.1bulbs(consumable product)dev.hyo.martie.premium(subscription)
From the root directory of the main project:
# Complete automated setup
yarn setup:expo
# This single command will:
# ✅ Install all root dependencies
# ✅ Install example-expo dependencies
# ✅ Run postinstall script (linking, building, prebuild)
# ✅ Generate native iOS/Android code
# ✅ Everything ready to run!After this, you can immediately run:
cd example-expo
bun ios --device # or bun ios for simulator
bun android# Install dependencies (this will run postinstall automatically)
bun install
# If you need to manually run the setup:
./scripts/postinstall.sh# Generate native code
bunx expo prebuild# Run on iOS simulator
bun run ios
# Or for device
bun run ios --device# Run on Android emulator/device
bun run android# Start Metro bundler
bun start-
Edit TypeScript code in the root
../src/directory -
Rebuild the library:
cd .. yarn prepare -
Restart Metro (or it should hot-reload automatically)
-
iOS: After modifying iOS native code
cd ios pod install cd .. bun run ios
-
Android: After modifying Android native code
bun run android
For testing in-app purchases on real devices:
# iOS Device
npx eas build --profile preview --platform ios
# Android Device
npx eas build --profile preview --platform android
# Or build locally
npx eas build --profile development --platform ios --local
npx eas build --profile development --platform android --local-
Sandbox Testing:
- Create sandbox tester accounts in App Store Connect
- Sign out of your personal Apple ID on the device
- Sign in with sandbox account when prompted during purchase
-
TestFlight:
- Upload build to TestFlight for more realistic testing
- Real users can test without sandbox accounts
-
Testing Track:
- Upload APK/AAB to internal/closed/open testing track
- Add test accounts in Google Play Console
-
License Testing:
- Add test accounts in Play Console > Settings > License testing
- Test accounts can make purchases without being charged
-
The bundle identifier
dev.hyo.martiemust match exactly in:- app.json configuration
- App Store Connect (iOS)
- Google Play Console (Android)
- Product IDs in the store consoles
-
Billing permissions are already configured in app.json:
- iOS: SKAdNetwork items for attribution
- Android:
com.android.vending.BILLINGpermission
- Ensure you're testing on a real device (not simulator for purchases)
- Check that the bundle ID matches store configuration
- Verify products are approved and available in store console
- Product IDs must match exactly (case-sensitive)
- Products must be approved in store console
- Wait 24 hours after creating new products
- Clear Metro cache:
yarn expo:start --clear - Clean build folders:
cd ios && rm -rf build && cd .. - Rebuild with
--clear-cacheflag