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.
npm installCRITICAL: 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 IDManual Setup:
- Get your EAS project ID from Expo Dashboard
- Or create a new project:
eas init
- Or create a new project:
- Open
app.config.jsand replace both placeholder values:- Line 80: Replace
YOUR_PROJECT_IDinurl: 'https://u.expo.dev/YOUR_PROJECT_ID' - Line 84: Replace
YOUR_PROJECT_ID_HEREinprojectId: 'YOUR_PROJECT_ID_HERE'
- Line 80: Replace
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.
# 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 productionThis project uses app.config.js to enable ProGuard configuration for Android release builds. The configuration includes:
Why ProGuard matters for this bug:
- The
DatabaseLaunchererror 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 buildsextraProguardRules- Custom rules to keep critical classes from obfuscationjavaCompileOptions- Java 17 compatibility settings- Core library desugaring enabled via
withCoreLibraryDesugaringplugin (required for reCAPTCHA)
ProGuard rules included:
- Core React Native rules:
# Keep React Native core classes
-keep class com.facebook.react.** { *; }
- 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.0react-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.
See REPRODUCTION_STEPS.md for detailed reproduction steps and affected devices.
Quick steps:
- Install the built APK on Android device
- Clear app data:
adb shell pm clear com.yourcompany.expoupdatesbug - Launch app (cold start)
- Crash occurs if embedded loader fails during startup
App should handle multiple launch() calls gracefully (idempotent or create new instance).
App crashes with AssertionError when launch() is called twice on same instance.