← Back to blog Khalil Drissi

Publishing a Flutter app to the App Store and Play Store

Listen to article
0:00

Writing the app is half the job. Getting it into both stores is the other half, and it is the half that surprises people. Apple and Google each have their own signing, their own metadata, and their own review moods. I have shipped through both more times than I can count, and the difference between a smooth release and a stressful one is preparation. Here is the path I follow.

Set the basics before you build

Before you generate a single release binary, get the boring fields right. A unique application id that you will never change, a sensible version and build number, the app name, and the minimum supported OS versions. Changing the application id after launch is effectively a new app, so decide it carefully. These live in the Gradle config on Android and the Xcode project on iOS.

# pubspec.yaml controls the version and build number
version: 1.0.0+1
# 1.0.0 is the version users see, +1 is the build number

Android signing and the app bundle

Google Play wants an app bundle rather than an APK now, and it wants it signed with an upload key you create once and guard carefully. Lose that key and you are in for a painful recovery process. I store the keystore outside the repository and reference it through a properties file that is never committed. Building the release bundle is a single command once signing is wired up.

flutter build appbundle --release
# produces build/app/outputs/bundle/release/app-release.aab

Upload that file to the Play Console, fill in the store listing, set up the content rating questionnaire, and choose a release track. I always push to internal testing first so I can install the exact artifact users will get before it goes public.

iOS signing and archiving

Apple signing is more involved. You need an Apple Developer account, certificates, an app id, and provisioning profiles. Xcode can manage most of this automatically if you sign in, which I recommend over wrangling profiles by hand. You build the iOS release through Flutter and then archive and upload through Xcode or the transporter tool.

flutter build ipa --release
# then open Xcode, archive, and upload to App Store Connect

Store listings take longer than you think

Both stores need screenshots at specific sizes, an icon, a description, keywords, a privacy policy URL, and a data collection disclosure. Apple is strict about the privacy questionnaire and will reject vague answers. Set aside real time for this, because a half done listing blocks the whole release. I keep a checklist so nothing gets missed at the last minute.

Surviving review

Apple review can reject for reasons that feel arbitrary until you read the guidelines closely. The common ones are missing demo account credentials, broken links, crashes on their test device, and unclear use of permissions. Give them a working login if your app needs one, test on a real device, and explain why you ask for each permission. Google review is usually faster and more automated but still cares about permissions and policy compliance.

Plan the updates too

Shipping version one is the start. Bump the build number every upload, keep a changelog, and use staged rollouts on Android so a bad release reaches a small slice of users first. The performance habits from Flutter performance optimization matter here because crash and jank metrics affect your store ranking. And if your app leans on native features, test those carefully across OS versions as I describe in Flutter platform channels. A calm release is a prepared release. Do the boring work early and launch day stops being scary.

Comments
Leave a comment