React Native & Expo: Create signed bundle for Android App

I’ve recently tried React Native for the first time, and the development process using Expo was delightfully easy. Now I’m trying to deploy the app to Google Play and it’s a pain, I’ve been reading docs for two days and I’m completely lost.

The Google Play part (using the Play Console) isn’t that much of a problem, but I’m unable to even create a production bundle. Plus, every attempt takes 15-20 minutes because I’m using Expo’s servers.

The issue is with the sign key/keystore. When trying to create the build with Expo, I’m asked if I would like to let Expo handle it for me, or if I’d like to provide my own key. Despite being clueless, I chose the latter, so I guess it’s my own fault… My reasoning was that I want the key/keystore on my computer, not on Expo’s servers, so I’m not tied to their services forever.

Ok here’s my steps:

I followed React Native documentation on how to create a keystore via command line:

keytool -genkeypair -v -storetype PKCS12 -keystore <filename> -alias <my-app-alias> -keyalg RSA -keysize 2048 -validity 10000

Next, I ran

expo build:android

and provided the file path to the .keystore file.

But this fails. The error logs from Expo (relevant parts):

> Task :app:signReleaseBundle FAILED
[stderr] FAILURE: Build failed with an exception.
[stderr] * What went wrong:
[stderr] Execution failed for task ':app:signReleaseBundle'.
[stderr] > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
[stderr]    > Failed to read key *************** from store "/tmp/turtle/keystore-0c2849b7-2d13-1234-b058-8647550a3503.jks": Invalid keystore format

What I’ve already tried:

expo fetch:android:keystore

This shows the correct alias/password I’ve used. But now I’m sort of lost. Problem is I have no idea what I’m doing. All totally new to me. Any advice would be awesome.

One thing I’d like to know, it would be great to have this sorted out: As long as I haven’t uploaded anything to Google Play yet, can I experiment over and over again, create new keystores, delete my credentials from Expo, try again with new key, without making some irreversible mistake?

As I understand it, once I upload an app to Google, it’ll look at the upload key (which at that point is the key I’ve stored on my computer, the one that I’ve signed the bundle with, the one that is tied to my Expo account, in the following referred to as THE key), and generate a sign key that will be used for the app’s certificate when it’s deployed and ready for download.

Whenever I upload another app, I’ll use THE key again to sign my bundle, and Google will create a different sign key for the downloadable app?

I’m trying to figure out which keys always have to be the same.

This is the tradeoff for using Expo. Unless you know exactly what you’re doing, you’re going to let Expo handle builds.

You can build yourself. You will lose out on ability to use the new optimised build pipeline (ie treeshaking of unused modules, ability to add native dependencies). But you can run their own build server (Turtle CLI) locally (or more likely on your own CI). But as I say, you need to know what you’re doing, and at this stage, you don’t.

Yeah that’s the thing, I want to know what I’m doing before I start uploading real apps to Google Play, especially concerning keys, because judging from the tons of “Halp” threads I’ve waded through in the last couple of days - if that isn’t done with at least some competence, I’d just make my own life miserable.

I’ve read about Turtle CLI, I wasn’t aware I could use a local server for the build. Plus I just realised that nothing holds me back from creating a few apps that only run on my phone, for testing purposes. Once I understand that and the whole building process, I can care about uploading to the store.

This is kinda the expected workflow. Actually deploying an app to the store isn’t really supposed to be an experimental thing – that’s likely the very last thing you want to do, after you have something you’re happy for consumers to use. You can’t really back out at that point. So everything in Expo is geared toward making the DX of developing toward this point as smooth as possible

Yeeeessss, you can do it, it’s the same program that runs Expo’s own build servers. Whether you want to do this is going to depend on whether you need control over the build process. I would say this is very important to have, but it’s obviously context-dependent (I am biased), and it’s going to be a [large] PITA to set up and run

However, what you cant get with that is the new build pipeline they’re rolling out ATM. And that produces optimised builds & allows native extensions (for example, non-expo push notifications or bluetooth).

I don’t think I’m at a point where I’m creating apps that would require much control over the build process, I just want to understand it. If you say it might be a large PITA to set it up, I totally believe you, but the bigger PITA is having to wait 20 minutes each time for your build to fail again. In the end I’ll explore it until I have sufficient understanding, and then I’ll hand it all over to Expo for convenience.

I’m…conflicted re Expo. And some of that is down to my particular situation: where I work, we need control over the build process: we can’t just chuck it over the wall to Expo build servers. Same situation as you describe. Whereas with a non-Expo RN app, I can just run a build, get an APK, and shove it on a phone.

The advantage of Expo from a dev PoV is huge. Not having to fire up Android Studio/XCode every time I want to build anything is amazing. But I’m not 100% sure that long-term that’s as great an advantage as it seems. Expo can be ejected, which still allows for the nice web UI and the link to the Expo app on a mobile device for quick development, but then it’s back to AS/Xcode, so :man_shrugging: I’m just not sure – the DX with Expo is great, but I’ve flip-flopped on this exact issue for about a year now, and I’m still not sure of the right answer. Other developers on team really like Expo, so that’s been the decider, and we managed to get around the issue of a few native libraries we had been using previously by finding alternatives within Expo-supported libraries.

I’d rely on the dev environment Expo provides, and I think much of the time this is fine – you can get it to a stage where you’re confident it’s all working and polished and will build without needing to actually run a build a lot of the time. However, if you’re at a point where it’s become burdensome, I’d seriously look at Turtle CLI and see if you can get a local build process running. It’s not too bad, it just requires that you take control (which is no bad thing, it’s just something that tends to be a little bit faffy and can get painful).

The developer experience is great. I tried React Native for the first time, and it took me one day to convert an existing React app into a Native app. Just expo start ed a server, scanned the QR code, and was coding with my phone next to me, with live preview and hot reload… OMG I’ve arrived in the future.

And then - deployment. Suddenly I have this huge unexpected road block in my face. Turtle CLI it is then. Reminds me of how I used CRA the first time and wasn’t happy with how much is abstracted away from me, I didn’t understand what was happening under the hood. So I built a few projects without CRA, gained some knowledge, then went back to CRA.

Expo tricked me into believing that developing for Android phones is a piece of cake, I give them full responsibility for my frustration >:-(
(and I haven’t even started yet to try an iOS build)

1 Like

Ah, hmm. So I assume you are on a Mac so you can run the build tooling (XCode). [caveat: rant, YMMV] Personal bugbear is that means ~30Gb free space is needed (about 5× the amount of space of the compressed download). JS gets mocked for the size of node_modules, but iOS development…ach. Up until about six months ago my work machine had a 256Gb drive, and that meant I couldn’t update XCode, and eventually couldn’t run RN iOS builds. Plus I only use XCode for RN builds, nothing beyond that, so it’s basically just gibberish anytime anything goes wrong, which is often, coupled to which XCode is an absolutely garbage program. Android isn’t much better, but at least it involves a much smaller installed size of crap needed to build. Plus sides of iOS dev are that emulation is good (and 1-to-1 if it’s a newer M1-powered machine, as it’s then effectively exactly same as iOS); Android emulation is crap and IME should be avoided (just plug a phone in and use that, always).

Hello no I just said that because while fighting my way through tons of tutorials, articles and documentation, I picked up that developing apps for Apple is even more of a hassle than for Android. I’ve no Apple products besides a 10 year old iPod, which I instantly hated because it forced me to install iTunes. And I’ve currently no intention to pay for an Apple Store developer account. Anyway I’ve prescribed myself a holiday this weekend, no code no docs. I need a break :desert_island:

Ah, you need to use Expo then, there’s no choice. Unless you’re only building for Android you can’t build locally: you need a machine capable of building iOS apps. This a critical advantage of Expo’s build servers handling things: you can build iPhone apps without needing XCode, as that’s installed on Expo’s servers rather than your machine.

1 Like

I only care about Android ATM since I have neither a Mac nor an Apple dev account, and both aren’t exactly cheap.

I’ve made some progress and got to a point where I could successfully create a dist folder with turtle, so it’s great that I got this far, the whole thing is quite frustrating but at least I always learn something (like how to get and set system environment variables and such).

The build failed though, with the error being:

ERROR: Failed to build standalone app
  err: Error: We don't support running standalone app builds for this platform on your operating system

Before I grind myself down completely - is it even possible to build for Android on a Windows machine? Because at the moment I don’t think it is. Or do I just need to install Android Studio?

Yes, but specifically for Turtle, you need Linux (or it’ll naturally work on a Mac) – it’s the program written for Expos own CI servers, and for that reason there’d have been no point making it work on Windows. So you’re going to need to run it on WSL or a VM. So you need Node, Turtle and JDK v8 installed on there + expo + your app code

Wow what a rabbit hole. Diving into WSL then, thanks for pointing that out.

1 Like

Yeah, and getting used to this is a good idea full stop. Get used to Linux: you may currently develop on Windows but you will inevitably develop/need to work on Linux at some point. WSL is part of MS’ response to this, definitely use it, it’s quite good.

Agree, and getting into Linux has always been a bucket-list thing for me. For now I’ve WSL with Ubuntu to get started, but I also have a 10 year old unused but functioning desktop computer lying around here, I always wanted to get that running with Linux. Seems the time has finally come.

1 Like

So…

  • I killed my old computer and installed Ubuntu
  • made myself familiar with it
  • figured out how to exchange files between my main Windows machine and the new Ubuntu machine (I could’ve used a stick but you know)
  • set up the development environment in Ubuntu

All because I was too impatient to wait for Expo’s servers 20 minutes each time, only for the build to fail.

Turned out that building for Android on a 10 year old machine with 4GB RAM is a bad idea. At least it hasn’t failed yet, but it’s been stuck at :app_minifyReleaseWithR8 for an hour.

I know I’ll either have to crawl back to Expo or I’ll have to buy new hardware, I’m just curious why creating a stand-alone App is so expensive. Mobile apps obviously should be quite small, what’s causing such insane system requirements (and what exactly are those requirements, I found quite a lot of contradicting information)?

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