Publish to Stores
Publishing a Flutter app: iOS App Store + Google Play. Signing, code review, store metadata, and OTA-like rollouts.
Flutter — publishing
EXAMPLE
# ===== iOS App Store ===== # Prerequisites: # - Apple Developer account (USD 99/year) # - Xcode + an iPhone for testing # 1. App ID + bundle identifier in Apple Developer Console # 2. Provisioning profile + distribution certificate # 3. Update version + build number: flutter build ipa --release --build-name=1.0.0 --build-number=1 # 4. Open ios/Runner.xcworkspace in Xcode # 5. Product -> Archive # 6. Distribute -> App Store Connect -> Upload # 7. In App Store Connect: add screenshots, description, keywords, age rating # 8. Submit for review (typically < 24 hours in 2026) # Pitfall: missing privacy manifest causes rejection. Add a PrivacyInfo.xcprivacy file. # ===== Android Play Store ===== # Prerequisites: # - Google Play developer account (USD 25 one-time) # 1. Generate signing key (once per app, keep SAFE forever): keytool -genkey -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 \ -validity 10000 -alias upload # 2. Wire keystore into android/app/build.gradle: # Reference signingConfigs.upload from buildTypes.release. # 3. Build app bundle: flutter build appbundle --release --build-name=1.0.0 --build-number=1 # Output: build/app/outputs/bundle/release/app-release.aab # 4. Play Console: create app, upload AAB to internal testing track # 5. Iterate: closed -> open -> production tracks # 6. Submit for review (typically a few hours in 2026) # Pitfall: lose the keystore = lose ability to update the app. BACK IT UP. # ===== Versioning ===== # pubspec.yaml version: 1.0.0+1 # Format: <semver>+<buildNumber>. iOS uses buildNumber for CFBundleVersion. # Bump version + build number per release. Build number must increase monotonically per platform. # ===== Code signing automation ===== # Fastlane + match for iOS: manages certificates + provisioning profiles via git. # Codemagic / Bitrise / Github Actions can build + sign + upload to TestFlight + Play. # fastlane match nuke development # clean up # fastlane match appstore # generate / sync # fastlane gym + pilot # build + upload to TestFlight # ===== Store metadata (both stores) ===== # - App name (up to 30 chars) # - Subtitle / short description # - Long description # - Keywords (iOS) / category (Play) # - Screenshots: at least 3-5, per device size # - App icon (1024x1024 PNG) # - Privacy policy URL # - Support email # ===== Beta + staged rollouts ===== # iOS: TestFlight (up to 10k external testers) # Android: internal / closed / open testing tracks, percentage-based staged rollout # ===== Updates ===== # Native code changes require a NEW app store release. # JS-only (no equivalent for Flutter natively; Dart is AOT-compiled). # For 'OTA-ish' updates: Shorebird (https://shorebird.dev) ships Dart patches over the air. # ===== Crash + analytics ===== # - Firebase Crashlytics (free, multi-platform) # - Sentry (open-source, paid hosted) # - Add BEFORE first release # ===== Patterns ===== # - Internal track -> closed beta -> staged production # - Crash reporting from day one # - Keep a release checklist (versions, screenshots, privacy) # - Fastlane / Codemagic for repeatable signing + uploads # ===== Pitfalls ===== # - Lost keystore = forever broken app # - Missing privacy manifest -> rejection # - Version code regression in Play Console # - Skipping internal testing -> production crashes
Why it matters
Publishing Flutter is a checklist exercise. Apple: bundle id + cert + Xcode archive + App Store Connect. Google: keystore (BACK IT UP) + AAB + Play Console. Use Fastlane / Codemagic for repeatability, Crashlytics from day one, staged rollouts for safety. The keystore is the single most important file in your project.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# Android: upload .aab via Play Console. # iOS: archive via Xcode, distribute through Transporter / App Store Connect.Try it Yourself »
Discussion
Loading…