Basically having the same problem as Disabling over the air updates for expokit apps(expo detached app). I have a React Native detached Expokit app using Expo SDK 32. We are building binaries on both iOS and Android. I have set expo.updates.enabled:false in app.json, but the Android build still picks up OTA updates whereas the iOS build does not.
Yes, I did re-build the APK and do a clean install of that APK after setting enabled:false but it still picked up the JS bundle from the build that came after it.
Advice on how to disable OTA updates on detached Android would be appreciated. Would rather not have to use the workaround of publishing to a different release channel for each build. Thanks.
Hi Adam, Iām running SDK 32.
I totally missed seeing this note though: ExpoKit : To change the value of enabled , edit ios/<PROJECT-NAME>/Supporting/EXShell.plist and android/app/src/main/java/host/exp/exponent/generated/AppConstants.java . All other properties are set at runtime.
Thank you for pointing it out. I had only set it in app.json. Let me try that and see if it works!
Hello @adamjnav. I set public static boolean ARE_REMOTE_UPDATES_ENABLED = false;
in AppConstants.java and did a build, but now the app will not launch. I get this exception
Uncaught Error: java.lang.Exception: Could not load embedded manifest. Are you sure this experience has been published?
So I would much appreciate advice on what to update in AppConstants.java as well as EXShell.plist. (Frankly Iām not too worried about EXShell.plist because my iOS builds do not pick up OTA updates)
I was having the same problem and I saw your answer and solved it. Thank you. The problem is you have to run āexpo publishā at least once before you make the APK.
package host.exp.exponent.generated;
import com.facebook.common.internal.DoNotStrip;
import java.util.ArrayList;
import java.util.List;
import host.exp.exponent.BuildConfig;
import host.exp.exponent.Constants;
@DoNotStrip
public class AppConstants {
public static final String VERSION_NAME = "2.9.2";
public static String INITIAL_URL = "exp://exp.host/@audere/FluAtHomeAU";
public static final boolean IS_DETACHED = true;
public static final String SHELL_APP_SCHEME = "expdcd6f73fcd53486284683e2a09a2d545";
public static final String RELEASE_CHANNEL = "default";
public static boolean SHOW_LOADING_VIEW_IN_SHELL_APP = false;
public static boolean ARE_REMOTE_UPDATES_ENABLED = true;
public static final List<Constants.EmbeddedResponse> EMBEDDED_RESPONSES;
public static boolean FCM_ENABLED = false;
static {
List<Constants.EmbeddedResponse> embeddedResponses = new ArrayList<>();
// ADD EMBEDDED RESPONSES HERE
// START EMBEDDED RESPONSES
embeddedResponses.add(new Constants.EmbeddedResponse("https://exp.host/@audere/FluAtHomeAU", "assets://shell-app-manifest.json", "application/json"));
embeddedResponses.add(new Constants.EmbeddedResponse("https://d1wp6m56sqw74a.cloudfront.net/%40audere%2FFluAtHomeAU%2F0.3.0%2F3d2736f22d04260cfded31c8dc9ee245-32.0.0-android.js", "assets://shell-app.bundle", "application/javascript"));
// END EMBEDDED RESPONSES
EMBEDDED_RESPONSES = embeddedResponses;
}
// Called from expoview/Constants
public static Constants.ExpoViewAppConstants get() {
Constants.ExpoViewAppConstants constants = new Constants.ExpoViewAppConstants();
constants.VERSION_NAME = VERSION_NAME;
constants.INITIAL_URL = INITIAL_URL;
constants.IS_DETACHED = IS_DETACHED;
constants.SHELL_APP_SCHEME = SHELL_APP_SCHEME;
constants.RELEASE_CHANNEL = RELEASE_CHANNEL;
constants.SHOW_LOADING_VIEW_IN_SHELL_APP = SHOW_LOADING_VIEW_IN_SHELL_APP;
constants.ARE_REMOTE_UPDATES_ENABLED = ARE_REMOTE_UPDATES_ENABLED;
constants.EMBEDDED_RESPONSES = EMBEDDED_RESPONSES;
constants.ANDROID_VERSION_CODE = BuildConfig.VERSION_CODE;
constants.FCM_ENABLED = FCM_ENABLED;
return constants;
}
}
With this current setting, the Android build picks up OTA updates.
If I change ARE_REMOTE_UPDATES_ENABLED=false then do a new build (which includes expo publish) then the app shows the āCould not load embedded manifestā error as mentioned above.
Thanks for responding @terri. I decided to call Updates.checkForUpdateAsync() on the most active screen in my app. Iām checking in componentDidMount(). If an update is available, I prompt asking if the user wants to install the update, then call Updates.reload(). The settings in app.json and EXShell.plist are set to default. This is a manual method which works on iOS and Android.
I am using react-navigation. I also added a checkForUpdateAsync() call in the NavigationEvents onDidFocus() handler. The application can now be updated OTA.