expo: [SDK 48] Bare workflow, android release w/ product flavors - "The embedded manifest is invalid or could not be read"

Minimal reproducible example

https://github.com/tylercote/bare-workflow-48

Summary

  1. Clone repo
  2. Open in Android Studio
  3. Select “developmentRelease” build variant
  4. Attempt to build on emulator
  5. The app crashes immediately upon launch with the following logcat output:
Could not get package user id: run-as: package not debuggable: com.barebones.app.dev
The embedded manifest is invalid or could not be read. Make sure you have configured expo-updates correctly in android/app/build.gradle. app.manifest

The only details I have changed from a fresh project:

  • Adding “app” package (i.e. com.barebones -> com.barebones.app)
  • Adding different product flavors, with different applicationId

My apologies if this is a project configuration issue rather than an Expo issue, but I saw the same issue posted elsewhere so I figured I’d try to create a minimal example of it happening.

#21238

Environment

expo-env-info 1.0.5 environment info: System: OS: macOS 13.0.1 Shell: 5.8.1 - /bin/zsh Binaries: Node: 17.9.1 - ~/.nvm/versions/node/v17.9.1/bin/node Yarn: 1.22.19 - ~/.yarn/bin/yarn npm: 8.11.0 - ~/.nvm/versions/node/v17.9.1/bin/npm Watchman: 2023.02.06.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.3 - /Users/tylercote/.rvm/gems/ruby-2.7.6/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 IDEs: Android Studio: 2022.1 AI-221.6008.13.2211.9514443 Xcode: 14.2/14C18 - /usr/bin/xcodebuild npmPackages: expo: ^48.0.4 => 48.0.4 react: 18.2.0 => 18.2.0 react-native: 0.71.3 => 0.71.3 npmGlobalPackages: eas-cli: 3.7.1 expo-cli: 6.3.1 Expo Workflow: bare

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 3
  • Comments: 37 (19 by maintainers)

Commits related to this issue

Most upvoted comments

@leymytel the fix is now in the SDK 48 maintenance branch. Will post again once a new expo-updates point release has been published.

@Johan-dutoit your solution is correct! Except that it will break the build if flavor variants are NOT used, as there will be duplicate copy tasks – but that is easy to fix. Thanks for providing this! 😄

I think the following patch against SDK 48 should work, @tylercote @ken0x0a @sin2 :

diff --git a/node_modules/expo-updates/scripts/create-manifest-android.gradle b/node_modules/expo-updates/scripts/create-manifest-android.gradle
index 81138a9..30b4d3f 100644
--- a/node_modules/expo-updates/scripts/create-manifest-android.gradle
+++ b/node_modules/expo-updates/scripts/create-manifest-android.gradle
@@ -69,6 +69,7 @@ def setupClosure = {
         name: "copy${targetName}ExpoManifest",
         type: Copy) {
       description = "expo-updates: Copy manifest into ${targetName}."
+      duplicatesStrategy = DuplicatesStrategy.INCLUDE
 
       into ("${appProject.buildDir}/intermediates")
       into ("assets/${targetPath}") {
@@ -90,6 +91,11 @@ def setupClosure = {
         from(assetsDir)
       }
 
+      // Workaround for Android Gradle Plugin 7.5+ asset directory (including flavor variants)
+      into ("assets/${variant.name}") {
+        from(assetsDir)
+      }
+
       // mergeAssets must run first, as it clears the intermediates directory
       dependsOn(variant.mergeAssetsProvider.get())
       dependsOn(currentBundleTask)

@Kudo

No idea if this is the right thing to do (or what the ramifications are)… but the following patch stopped my crashing

diff --git a/node_modules/expo-updates/scripts/create-manifest-android.gradle b/node_modules/expo-updates/scripts/create-manifest-android.gradle
index 81138a9..b5896e4 100644
--- a/node_modules/expo-updates/scripts/create-manifest-android.gradle
+++ b/node_modules/expo-updates/scripts/create-manifest-android.gradle
@@ -86,7 +86,7 @@ def setupClosure = {
       }
 
       // Workaround for Android Gradle Plugin 7.1+ asset directory
-      into ("assets/${variant.name}/merge${targetName}Assets") {
+      into ("assets/${variant.name}") {
         from(assetsDir)
       }

Fixed in expo-updates@0.16.4

for sdk 48, that might be related to https://github.com/expo/expo/blob/11c0cbb32e6867b1e2103353493c452d240c4e98/packages/expo-updates/scripts/create-manifest-android.gradle#LL65C21-L65C22

You can avoid this error by put project.ext.react back to “android/app/build.gradle”

project.ext.react = [
  bundleInDev: true,
  bundleInYourFlavourInPascalCase: true,
]

for sdk 48, that might be related to https://github.com/expo/expo/blob/11c0cbb32e6867b1e2103353493c452d240c4e98/packages/expo-updates/scripts/create-manifest-android.gradle#LL65C21-L65C22

You can avoid this error by put project.ext.react back to “android/app/build.gradle”

project.ext.react = [
  bundleInDev: true,
  bundleInYourFlavourInPascalCase: true,
]

@ken0x0a This unfortunately did not fix the crash in my case.

Can confirm that the patch above works for me.

Thanks @Johan-dutoit this is extremely helpful 👍

@douglowder yeah, I saw that.

I might misinformed. I’m using buildType and not flavor. Without bundleInDev,

...
Task :expo-updates:copyDevExpoManifest SKIPPED
...

will happen right? Or, is there another reason for this skip?

As I followed the code, I found that code is the one I was looking for, and The embedded manifest is invalid or could not be read. was fixed in my case.

Interesting

Ok to make things simpler, I reproduced the issue a different way.

  • Execute the following:
yarn create expo-app bare-workflow-48 --template blank-typescript
cd bare-workflow-48
eas init
eas update:configure
  • Modify app.json to add request headers for updates:
{
  "expo": {
.
.
.
    "updates": {
      "requestHeaders": {
        "expo-channel-name": "main"
      },
      "url": "https://u.expo.dev/_project_id_"
    }
  }
}
  • Execute npx expo prebuild and select the default package name and bundle identifier (in my case, it was com.douglowderexpo.bareworkflow48)
  • Build and run the Android app
cd android
./gradlew :app:installRelease

App will start as expected.

  • Now edit android/app/build.gradle as follows to add some variants:
    flavorDimensions "default"
    productFlavors {
        local {
            applicationId "com.douglowderexpo.bareworkflow48.local"
        }   
        development {
            applicationId "com.douglowderexpo.bareworkflow48.dev"
        }   
        production {
            applicationId "com.douglowderexpo.bareworkflow48"
        }   
    }   
  • Try building and installing one of the variants:
cd android
./gradlew :app:installDevelopmentRelease

It will cause the missing manifest crash described in this issue.

I suspect that the build flavors need additional lines in the build files to properly create and package the updates manifest.

@douglowder @bebe84

I am now seeing the crash that you mention @bebe84, as I had previously forgotten to update the native code as mentioned here. Upon updating the native code, it is returning to crashing on launch. I have updated the repro in my original issue to indicate this.