Skip to content

louveshh/minimal-reproducible-example-expo-updates

Repository files navigation

expo-updates DatabaseLauncher Bug - Minimal Reproducible Example

Bug

java.lang.AssertionError: DatabaseLauncher has already started. Create a new instance in order to launch a new version.

Location: expo.modules.updates.launcher.DatabaseLauncher.launch() at line 73

Cause: In LoaderTask.launchFallbackUpdateFromDisk(), if EmbeddedLoader.load() throws an exception after launcher.launch(database) is called, the catch block calls launch() again on the same instance.

Setup

1. Install Dependencies

npm install

2. Configure EAS Project ID ⚠️ REQUIRED

CRITICAL: You MUST set a valid EAS project ID before building. The placeholder values (YOUR_PROJECT_ID_HERE) will cause the build to fail with "Invalid UUID appId" error.

Quick Setup (Recommended):

eas init
# This will automatically create a new EAS project and update app.config.js with the project ID

Manual Setup:

  1. Get your EAS project ID from Expo Dashboard
    • Or create a new project: eas init
  2. Open app.config.js and replace both placeholder values:
    • Line 80: Replace YOUR_PROJECT_ID in url: 'https://u.expo.dev/YOUR_PROJECT_ID'
    • Line 84: Replace YOUR_PROJECT_ID_HERE in projectId: 'YOUR_PROJECT_ID_HERE'

Example (what it should look like):

updates: {
  fallbackToCacheTimeout: 1000,
  url: 'https://u.expo.dev/2c034a0d-94a5-40cc-b7f7-59eabb28c306',  // ← Replace YOUR_PROJECT_ID
},
extra: {
  eas: {
    projectId: '2c034a0d-94a5-40cc-b7f7-59eabb28c306',  // ← Replace YOUR_PROJECT_ID_HERE
  },
},

Note: The project ID is a UUID format (e.g., 2c034a0d-94a5-40cc-b7f7-59eabb28c306). Both values must be the same UUID.

3. Build

# Clear Metro cache if you encounter module resolution issues
rm -rf node_modules/.cache .expo

# Build for development (local build)
npm run build

# Or build for production
eas build --platform android --profile production

Configuration

app.config.js

This project uses app.config.js to enable ProGuard configuration for Android release builds. The configuration includes:

ProGuard Configuration

Why ProGuard matters for this bug:

  • The DatabaseLauncher error occurs in native Android code (Kotlin)
  • ProGuard obfuscation can make stack traces unreadable
  • Keeping expo-updates classes ensures clear error messages

Configuration details:

  • enableProguardInReleaseBuilds: true - Enables ProGuard for production builds
  • extraProguardRules - Custom rules to keep critical classes from obfuscation
  • javaCompileOptions - Java 17 compatibility settings
  • Core library desugaring enabled via withCoreLibraryDesugaring plugin (required for reCAPTCHA)

ProGuard rules included:

  1. Core React Native rules:
# Keep React Native core classes
-keep class com.facebook.react.** { *; }
  1. Additional ProGuard rules:
    • These rules are included to ensure proper ProGuard configuration for the installed dependencies
    • The corresponding libraries are installed as dependencies:
      • react-native-svg: 15.12.1
      • @stripe/stripe-react-native: ^0.54.1
      • @google-cloud/recaptcha-enterprise-react-native: ^18.8.0
      • react-native-appsflyer: 6.17.7
      • @react-native-firebase/app: ^23.4.1
      • @react-native-firebase/remote-config: ^23.4.1
# react-native-svg
-keep public class com.horcrux.svg.** { *; }
-dontwarn com.horcrux.svg.**

# Stripe SDK
-keep class com.stripe.android.** { *; }
-keep class com.stripe.android.pushProvisioning.** { *; }
-dontwarn com.stripe.android.pushProvisioning.**
-keep class com.google.common.** { *; }
-dontwarn com.google.common.**

# Google reCAPTCHA Enterprise
-keep class com.google.android.gms.internal.recaptchabase.** { *; }
-keep class com.google.android.gms.internal.recaptchabase.zzm$Companion { *; }
-dontwarn com.google.android.gms.internal.recaptchabase.**

# AppsFlyer SDK
-keep class com.appsflyer.** { *; }
-keep class kotlin.jvm.internal.** { *; }
-keep class com.appsflyer.internal.AFj1eSDK$Companion { *; }
-dontwarn com.appsflyer.**
-dontwarn kotlin.jvm.internal.**

This project uses app.config.js for configuration. The splash screen uses a simple blue background (#0066FF) without requiring image assets, keeping the minimal repro setup simple.

Reproduce

See REPRODUCTION_STEPS.md for detailed reproduction steps and affected devices.

Quick steps:

  1. Install the built APK on Android device
  2. Clear app data: adb shell pm clear com.yourcompany.expoupdatesbug
  3. Launch app (cold start)
  4. Crash occurs if embedded loader fails during startup

Expected

App should handle multiple launch() calls gracefully (idempotent or create new instance).

Actual

App crashes with AssertionError when launch() is called twice on same instance.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published