Android app does not load bundled JS version even on a complete uninstall/ reinstall

I previously reported this issue: In short, what happens on Android 6.0 and older devices is, when you install a standalone APK that was built against a later version of the JS bundle over an older version, the first time you load the app, it still loads the old bundle on first run. Meanwhile, Android 7.0 and later devices load the JS bundle that was actually packaged with the app. The net result is that android 6.0 and older users who are updating an app through the Play Store need an extra app restart to see the latest JS (and even though they see that Google Play updated their app, it doesn’t look like they got any updates).

I’m noticing a new, related issue. I just updated our app in the Play Store from an APK with SDK 22 (let’s call this version 1.0.0) to one with SDK 25 (version 1.0.1). On an Android 6.0 device where I had previously installed 1.0.0, but later uninstalled it, when I install the latest version from Google Play, on first run, the JS bundle version is the last version that I was downloaded when I had version 1.0.0 installed (an OTA update that was pre-1.0.1). No matter how many times I uninstall/ reinstall the app from Google Play, it always first loads on that old JS bundle.

This did not happen on an Android 7.0 device I tried, and it did not happen on an Android 5.1 device where I had not previously installed my app. It seems like something about this JS bundle is cached on my Android 6.0 device, and it never goes away even after a full uninstall. I wanted to see if this is the same case with sideloading the APK, but since I’ve installed the latest version from Google Play, every time I uninstall the GPS version and sideload the APK, it crashes on first load. Then the second load has the latest JS bundle.

This is more concerning than the original bug, because it now seems like certain users can have the JS bundle version of the Android app go backwards (if they uninstall and reinstall the app later). Android 6.0 and earlier is still about 75% of the market. At some point, I would like to deprecate old versions of our server API as we upgrade the app and Google Play Console analytics show that users are no longer using those old versions, but I would have to leave those versions in place if some users can travel back in time to a really old version of the app.

Obviously, this is kind of hard to debug since it involves a somewhat specific series of things that happened on a particular phone. If it helps, I’m happy to provide the APK’s or test accounts for our app. Thanks!

Hi @llamaluvr, thanks for reporting this issue. Our manifest serving/publishing behavior has changed over the last couple SDKs, so it is hard to root cause exactly what is going on, but here are some things that could help:

  1. We’ve also seen some Android devices that dont delete all of the Expo app data even when we’ve uninstalled the app. This is most likely due to the always-enable-backups feature Android has for v6, especially since you mentioned it is Android 6:

I’ll look into fixing this issue in the manifest.xml, but in the meantime, is it possible for you to nuke the backups on your Android 6 device so you can be unblocked?

  1. When we decide what js experience to send back to the user, we choose the most recent compatible release – it must be a compatible SDK version published to the Android platform.


Regarding nuking the backups, do you know how to do that? I don’t see anything obvious on Google for deleting a backup. I do see an option in my phone for turning backups off. Is that what you mean?

Regarding item #2, I don’t see anything specifically about the JS bundle behavior when updating to a new APK there or elsewhere in the Expo docs, but I have heard from others on the Expo team that the user should see the JS bundle packaged into the APK on first load of the app after the app is installed/ updated from the Play Store. Indeed, this works exactly as I just described on Android 7.0 and later. My original bug report (Github link) pertains to Android 6.0 and earlier not showing the JS included with the APK after a GPS update. Just wanted to clarify that, in case you except something different to happen.

So, if the backups are the issue with this (new) bug I’ve just reported now, you’re thinking that maybe this is only a 6.0 thing, because a) that’s the first version where backups were automatically enabled, and b) it’s the last version where Expo doesn’t use the JS bundled with an APK update on first load?

hey @llamaluvr,

re item#1: Yes, try that and see if it works. I’m not quite sure how to do it either – stack overflow says to change the manifest.xml, which we are working on, but maybe there is an option in settings on the device itself to disallow backups?

re item#2: Ok, that makes sense. The issue you describe is a bug, since the expected behavior should be the same, regardless of Android version.

overall: Yes, my hypothesis is that it is an Android 6 thing, but if you’ve seen data sticking around even after an uninstall for earlier Android versions, let us know!

hey @llamaluvr - thanks for all of your detailed reports. Reading that SO link that @quinlanj posted, there is an answer farther down that describes how to turn off auto-restore of backups (which seems to be the key, rather than turning off the backups themselves)

When you get a chance, could you give this a try and let us know if that fixes this issue? Unfortunately I have not been able to reproduce it, so any confirmation would be super helpful on our end.

FYI, in SDK 26 we have done some overhauling of the OTA updates logic which, as a side effect, should fix both this issue and your original GH one (#1122) for the online case (though both issues will likely still persist anytime the client is unable to grab the latest JS). We’ll have some more improvements and fixes for this process in future versions as well.

Thanks @esamelson and @quinlanj! I tried this a bunch of times. The results were definitely different than I got before with auto-restore off, and I definitely didn’t see any old versions load, though there was lots of hanging and crashing unfortunately.

I probably tried about 15 uninstall/ install cycles. Most of the time, this is what would happen:

  1. Uninstall app.
  2. Install app.
  3. Open app.
  4. Splash screen shows, but never goes away.
  5. Eventually, Android OS would ask if I would like to kill the app.
  6. I’d kill the app.
  7. Then I’d open the app again.
  8. Everything would work, and it would be on the version included with the APK (which is also the latest version at the moment).

One time, I did this, and the app started up the very first time on the latest version. This was directly after a reboot that was after an uninstall. However, I tried rebooting a few more times and it acted like it did above, hanging the first time.

3-4 times, instead of hanging on the first open, it crashed almost immediately. Then the second time it loaded up OK with the latest version.

Maybe 3 times, it hung at the splash screen on first open. I killed the app. Then on second open in hung on a blank screen (same color as splash screen, but no splash image). On third open, it’d do the same thing, except the one time where it hung on a blank screen that was “Expo blue” color. Then on the fourth open it’d work correctly. This happened more towards my later tests. Maybe my phone is getting tired :stuck_out_tongue_winking_eye:.

I didn’t try cutting the network during any of these steps, but could try that if you think it’d be informative. Oh, and I tried several times with backup set to on and off- that didn’t seem to have any effect.

I should note that we had an Android 8.0 user experience this “crash/ hang on first load” issue multiple times during our last testing cycle. They didn’t see any unexpected old versions, though. In both his and my case, our devices have had both the Google Play Store install and the sideloaded APK installed at some point. We had Expo generate our certs, but with Google Play Protect enabled on our app, that means that the GPS version is technically signed with a different key. Figured I’d mention this in case it brings anything to mind.

Stoked that this area is seeing some improvements in upcoming SDK’s. Thanks so much for making this an area of focus! I definitely understand this is the sort of thing that can be hard to reproduce, or to definitively say you’ve solved it when you make a change- but can clear up as the code is improved, error checking is beefed up, etc. I’ll be sure to run SDK 26 through a battery of tests like I have before and let you know what I see. Thanks!

Hey @llamaluvr - thanks very much again for your testing and super detailed reports. Sad to hear this :frowning: I will prioritize trying to fix the offline case as well before SDK 26 goes out.

As a side note, there is a sporadic “crash/hang on load” issue that will definitely be fixed in SDK 26, and is unrelated to the problem of choosing which bundle version to load, so perhaps that caused some of the other crashes you were seeing as well? I can’t be sure of this, though, since I’m still unable to reproduce the backup/restore issue.

Thanks again, we really appreciate all of your help here!! Will try and keep you up to date with any progress we make.

1 Like

hi @llamaluvr - just wanted to let you know that although SDK 26 has been delayed for another few weeks, we’ve just deployed a minor update to Android (both the client and standalone app builder) that includes fixes for both this and your original issue. So you should be good to go if you build a new version starting ~now. Let us know if that’s not the case. Thanks so much!!

Awesome! I’ll try it out soon. Just to clarify, when it comes to building a standalone app, this is a server-side only change? So I don’t need to update my Expo version to a new point release (e.g., 25.0.1 or something) to test it out?

Yes, that’s correct, no need to change anything on your end.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.