FlutterGo builds, signs and uploads your Android app to Google Play from its own cloud, on the same build machine that makes your APKs. You open Ship → Deploy, fill in three short steps once, and click Deploy. You don't need GitHub, a Mac or Android Studio.
While a deploy runs, a small map shows the road your build travels: App → FlutterGo → Play.
The App Store is a separate deploy with its own tab. See Publishing to the App Store.
What you need#
- FlutterGo Pro or higher. Store deploy is a Pro feature.
- 2.5 credits for each Google Play deploy. Deploying Google Play again for the same project within 24 hours is free, and a deploy that never reaches Google Play is refunded. In a shared project, the owner's plan and credits pay.
- A Google Play developer account (Google charges a one-time $25 registration fee) and your app created in Play Console.
- Access to your Play account. The easy way is to connect Google Play by signing in with Google. The advanced way is a Play service-account JSON key with release access to your app; Create the Play service-account JSON shows how, step by step.
- An upload keystore (
.jksor.p12). No keystore yet? FlutterGo can generate one for you.
Connect Google Play and sign in with Google#
The easiest way to give FlutterGo access to Google Play is to sign in with the Google account you use for Play Console. You don't need Google Cloud, a service account or a key file.
Connect your account#
- In Ship → Deploy → Google Play, go to the Credentials step and click Connect Google Play.
- A Google sign-in window opens. Choose the Google account that has your app in Play Console, and approve the access FlutterGo asks for.
- The window closes and the wizard says Connected as your email. Use Use another account to switch to a different Google account.
Pick your app and deploy#
- FlutterGo lists the apps this Google account can reach in Play Console. Click yours. FlutterGo fills in the package name for you, and writes it into your project when you deploy.
- FlutterGo checks the app right away and tells you one of three things: Ready to push, Upload the first bundle by hand once, or This Google account cannot release this app.
- Add your signing key as usual (see Step 3: Credentials), then continue to Review & deploy and click Deploy.
If your app is not in the list, click My app is not in the list. FlutterGo keeps the package name it proposes for your project. Google sometimes leaves apps that were never published out of this list, and a brand-new app has no package name on Google Play until its first build is uploaded.
If the check says this account cannot release the app, ask the Play Console account owner to give your Google account Release apps to testing tracks for this app in Users and permissions, or connect a different account.
The first build of a new app#
Google Play takes a new app's very first build only in Play Console, never from FlutterGo or any other tool. You do this once per app. After that, every build goes up automatically.
When the check says the first build is missing, Deploy builds and signs your app, and the wizard shows Your turn: upload the first build with three tasks, one at a time:
- Download your app file. Click Download app file. The wizard says how long FlutterGo keeps it.
- Upload it in Play Console. Click Open Play Console and open your app. Go to Test and release → Testing → Internal testing and click Create new release. If Play Console asks about Play App Signing, keep the option Google recommends. Click Upload, choose the file you downloaded, then click Save as draft. Back in FlutterGo, click I uploaded it.
- FlutterGo finds your app. You don't need to do anything. FlutterGo checks Google Play every few seconds, and also when you come back to the tab; Check now checks at once. When Google knows your app, the wizard says All done. FlutterGo pushes your builds now.
You can close the wizard at any time; it keeps your place. Don't deploy that same build again: Google Play already has its build number. Your next deploy goes up on its own.
Tip: Google sometimes renames menus in Play Console. If you can't find Internal testing, look for Testing in the left menu of your app.
What access FlutterGo gets#
When you connect, Google shows what FlutterGo asks for. There are two parts:
- Publishing access to your Google Play apps, so FlutterGo can upload the builds you ask it to deploy, with your release notes and track.
- Read access to your list of Google Play apps, used only to show the apps you pick from.
FlutterGo uses this access only when you deploy or open the app list. It does not change prices, store listings or other settings, and does not read your financial data. Your connection is stored encrypted and is never shared. See the privacy policy for details.
Disconnect Google Play#
- In the wizard, click Disconnect next to Connected as. FlutterGo deletes its copy of your connection.
- You can also remove FlutterGo's access from your Google account at any time: open your Google account settings, go to Security → Your connections to third-party apps & services, choose FlutterGo and remove access.
If Google stops accepting the connection (for example after you remove access, or change your password), the wizard asks you to connect again.
Use a service-account key instead#
The service-account JSON key still works and is useful for teams that already have one, or for deploys that must not depend on one person's Google account. In the Credentials step, open Use a service-account key instead and follow Create the Play service-account JSON.
How to do it#
Step 1: Open Deploy on the Google Play tab#
In the right panel, click Ship → Deploy. The deploy wizard opens with two tabs at the top: Google Play and App Store. Choose Google Play.
The Google Play steps are App details, Credentials and Review & deploy. There is no GitHub step: FlutterGo's cloud does the build and the upload.
Tip: Each store has its own tab and deploys on its own. A Google Play deploy never waits for the App Store, and both can run at the same time. Each tab shows a small status while it works: Deploying, Shipped or Failed.
On a plan below Pro, the wizard says store deploy comes with Pro and shows See Pro. You can look through the steps, but the deploy starts only once your plan includes it.
Step 2: App details#
The App & release step asks for the track and the version:
- Release track: where the build goes. See Release tracks below.
- Version (build name), for example
1.0.0. Leave it empty to use the version in yourpubspec.yaml. - Build number, for example
1. Leave it empty and FlutterGo uses one past your last deploy (and past yourpubspec.yaml), so Google Play never sees the same number twice. - Release notes / What to test: Google Play shows them as What's new. Google allows up to 500 characters.
- Staged rollout %: appears only when the track is Production.
Click Continue.
Step 3: Credentials#
The Store credentials step says: "Your keys are stored safely and saved for next time." Fill in the Android · Google Play section. Its badge shows Ready, or how many items are still missing.
- Package name: your Android application ID, for example
com.yourcompany.yourapp. FlutterGo fills it in from your project. If you change it here, FlutterGo writes the new name into your project when you deploy. Once your app has a build on Google Play, this must match the package name Play Console shows for it exactly. - Your Play access: click Connect Google Play (see Connect Google Play and sign in with Google), or open Use a service-account key instead, click Choose file and pick the Play service-account JSON key. A check mark shows when it has loaded.
- Your signing key. Pick one:
- Click ✨ Generate keystore for me. FlutterGo creates an upload key and its
key.propertiesand saves them in your project underandroid/. - Or upload your own: choose your keystore under Upload keystore (.jks / .p12), then paste your key.properties contents (
storePassword,keyPassword,keyAlias,storeFile). For a.p12file, FlutterGo addsstoreType=PKCS12for you. If your project already has anandroid/key.properties, Copy from android/key.properties in project fills the box.
If something is still missing, a Still needed box at the top lists it. Continue stays disabled until every item is there.
If FlutterGo generated your keystore: save the backup#
A panel appears: Save your signing files, once. Click Download signing backup (required). You get the keystore file, key.properties and a password backup. Continue stays disabled until you have downloaded the backup at least once.
Important: Keep this backup somewhere safe. Google Play needs the same upload key for every update, and FlutterGo cannot recover it for you. The keystore never goes to GitHub and is not part of Download code, so this backup is your copy.
Saved for next time#
FlutterGo keeps an encrypted copy of these keys with your project, so the wizard is already filled in for your next deploy. Saved files show a check mark and a Replace button, and the key.properties box says "Saved — paste only to replace". Saved keys are never shown in your browser again.
Tip: If you deployed to Google Play before FlutterGo moved Play builds to its own cloud, your Play keys may only exist as secrets in your GitHub repository. GitHub never gives saved keys back, so the wizard asks you to add them here one more time: "You added this before, but FlutterGo's copy was lost (that's fixed now)." After that they stay saved.
Step 4: Review & deploy#
The review shows Built by (FlutterGo cloud), Store (Android · Google Play), Track, Version, Android package, Play service account and Android signing. The line under the buttons says how many credits this deploy uses, or that there is no charge because this project already paid for a Google Play deploy in the last 24 hours.
Click Deploy.
Tip: This step also shows a GitHub Actions preflight box. It is for App Store deploys. A Google Play deploy does not use GitHub, so you can ignore what it says about GitHub.
Step 5: Watch it ship#
The ship map follows your build from App to FlutterGo to Play. The stop being worked on pulses, a finished stop gets a check mark, and a failed one shows !. The line above it says what is happening, for example Building release while FlutterGo builds your app, then Uploading to store while it sends it to Google Play.
You don't have to wait. Click Run in background and keep working. In Ship, a Deploy: status (for example Deploy: Building) stays visible until the deploy ends; click it to open the wizard again, or click Cancel to stop the deploy. Inside the wizard, Stop deploy does the same.
Success: The wizard shows a line such as Live on Google Play "internal" (versionCode 12). Your build appears in Play Console on the track you chose.
If your app has never been published on Google Play, Google accepts new releases only as drafts. FlutterGo then uploads the release as a draft and tells you so: open Play Console, finish the store listing, and roll the draft out.
Tip: After your first deploy, you can also ask in the chat, for example "deploy to Google Play". The agent asks which store, proposes the next version and build number, and starts the deploy when you choose Yes, start now. Your message costs 1 credit like any chat message, and the deploy costs its usual 2.5 credits.
Release tracks#
| Track (wizard label) | Who sees it | Typical use |
|---|---|---|
| Internal testing | Up to 100 testers you invite | First tests, fastest review |
| Closed testing (alpha) | Invited groups / email lists | Private beta with a bigger group |
| Open testing (beta) | Anyone who joins from the Play listing | Public beta before launch |
| Production | Everyone on Google Play | The real release, supports Staged rollout % |
Tip: Staged rollout % (Production only) releases to a share of users first, for example 10. Leave it blank for a full 100% release.
Important: Production publishes to real users after Google's review. Start on Internal testing for your first deploy.
Create the Play service-account JSON#
The service account is a robot Google account that FlutterGo uses to upload releases for you. You create it once. Use the same Google Cloud project for parts A and B.
A. Turn on the Google Play API#
- Open the Google Cloud console and sign in. If you don't have a project yet, create one from the project picker at the top.
- Open APIs & Services → Library, search for Google Play Android Developer API, open it and click Enable.
B. Create the service account and its JSON key#
- In Google Cloud, open IAM & Admin → Service accounts and click Create service account.
- Give it a name, for example
fluttergo-deploy, and click Create and continue. It needs no Google Cloud roles: click Continue, then Done. - Copy the service account's email address. It ends in
iam.gserviceaccount.com. You need it in part C. - Open the service account, go to the Keys tab, click Add key → Create new key, choose JSON and click Create. A
.jsonfile downloads.
Important: Treat this file like a password. Anyone who has it can release builds of your app. Don't email it or put it in your project files; add it only in the deploy wizard.
C. Give it release access in Play Console#
- Open Play Console and go to Users and permissions for your developer account.
- Click Invite new users and paste the service account's email.
- Under App permissions, add your app and turn on Release apps to testing tracks. If you will deploy to Production, also turn on Release to production, exclude devices, and use Play App Signing.
- Save the permissions and click Invite user.
D. Add it to FlutterGo#
In Ship → Deploy → Google Play → Credentials, click Choose file next to Play service-account JSON and pick the downloaded file. FlutterGo saves it, encrypted, for every deploy after this one.
Tip: To deploy another app with the same key, give the service account access to that app in Play Console too.
A brand-new app: the first upload by hand#
If you connected Google Play with your Google account, the wizard guides you through this step: see The first build of a new app. With a service-account key, it works like this.
Google Play takes a new app's very first build only in Play Console, never through its API. So the first deploy of an app Google Play has never received a build for fails with "Package not found". That is expected, and FlutterGo has already done the hard part: it built and signed the app bundle, kept it, and refunds the credits for that try.
- In the failed deploy, click Download app bundle (.aab). The bundle is kept for 7 days; the line next to the button says until when.
- In Play Console, create the app (Create app) if you have not yet. Google Play takes the app's package name from this first bundle.
- Open Internal testing, click Create new release, upload the
.aaband save the release. - Deploy again from FlutterGo. Later builds go up automatically.
Tip: When you upload the first bundle, Play Console may ask how the app is signed. Google signs the app for its users with its own key (Play App Signing); the keystore you use in FlutterGo stays your upload key.
What happens during a deploy#
- FlutterGo sends your project to its build machine and builds a release Android App Bundle (
.aab) with your version and build number. - New Flutter apps sign release builds with a debug key, which Google Play refuses. The first time, FlutterGo points your release build at your upload key (
android/key.properties). - Server-only keys you saved, such as a payment secret key, are kept out of the app.
- FlutterGo uploads the bundle to your chosen track with the Google Play Developer API, with your release notes and rollout.
- No GitHub repository, Actions minutes or GitHub secrets are involved.
- If the deploy fails after the build, FlutterGo keeps the signed bundle for 7 days.
- A deploy that never reaches Google Play gives back its 2.5 credits. The log says, for example, "2.5 credits refunded: nothing reached Google Play."
From the command line#
The od command line tool can follow and finish Google Play deploys too:
od flutter deploy status --project <id>shows the latest deploy, its failed step and its log.od flutter deploy cancel --project <id>stops a running deploy.od flutter deploy bundle --project <id>prints a download link for the app bundle a failed Google Play deploy kept, the same file as Download app bundle (.aab).
Add --json to any of them for machine-readable output.
Troubleshooting#
Problem: Google Play says "Package not found". Possible causes: The app has never received a build on Google Play, or the package name doesn't match Play Console. Solution:
- For a brand-new app, follow A brand-new app: the first upload by hand.
- If you already uploaded a first build, check that Package name in the wizard matches your app in Play Console exactly.
Problem: The app built, but Google Play refused the upload because the service account has no permission. Possible causes: The service account was not invited in Play Console, or it lacks release rights for this app. Solution:
- In Play Console → Users and permissions, invite the service account's email and give it Release apps to testing tracks for this app (and the production permission if you deploy to Production). See part C.
- If you only just invited it, wait a little, then click Deploy again.
Problem: The Google Play Android Developer API is turned off. Possible causes: The API is not enabled in the Google Cloud project that owns the service account. Solution:
- Enable Google Play Android Developer API in that project (part A).
- Wait a few minutes, then click Deploy again.
Problem: Google rejected the Play service-account JSON. Possible causes: The file is not a service-account key, or the key was deleted or revoked. Solution:
- Create a new JSON key for the service account (part B).
- In Credentials, click Replace next to Play service-account JSON and pick the new file.
Problem: Google Cloud won't let you create a key. Possible causes: A policy in your Google Cloud organization blocks service-account keys. Solution:
- Ask whoever manages your Google Cloud organization to allow key creation for this project, or use a project outside that organization.
Problem: The deploy fails at Build the App Bundle. Possible causes: The app does not compile as a release build. Solution:
- Click Fix with agent. FlutterGo hands the failure log to the agent, which fixes the project. Like the Fix with AI button, this repair doesn't use a credit.
- Click Deploy again.
Problem: Google Play rejects a bundle signed with the debug key, or Android signing fails. Possible causes: The upload keystore or its key.properties is missing or doesn't match. Solution:
- In Credentials, upload the keystore and paste its matching key.properties contents together, or click ✨ Generate keystore for me.
- Check that the package name matches your Play Console app, then deploy again.
Problem: Google Play says this version code has already been used. Possible causes: Google Play already has a build with this build number. Solution:
- Clear Build number so FlutterGo picks the next one, or enter a higher number, then deploy again.
Problem: Continue is disabled on the Credentials step. Possible causes: A field in Still needed is empty, or you generated a keystore and have not downloaded its backup. Solution:
- Add each item the Still needed box lists.
- If you generated a keystore, click Download signing backup (required).
Problem: The wizard says "We couldn't load your saved keys. Store deploys need an active Pro plan on the project owner's account." Possible causes: The project owner's plan is below Pro, or its payment did not go through. Solution:
- The project owner upgrades to Pro, or updates the payment method, in Plans & billing. See Plans, credits & billing.
Problem: The Deploy button says Need 2.5 credits. Possible causes: The account that pays for this project has fewer than 2.5 credits left. Solution:
- Buy a credit pack or upgrade in Plans & billing, then come back and click Deploy.
Problem: "A Google Play deploy is already running." Possible causes: Each store runs one deploy at a time. Solution:
- Wait for it to finish, or click Stop deploy, then start again.
FAQ#
What does a Google Play deploy cost? Google charges a one-time $25 fee for the developer account. In FlutterGo, store deploy needs Pro or higher and costs 2.5 credits per Google Play deploy. Deploying Google Play again for the same project within 24 hours is free, and a deploy that never reaches Google Play is refunded.
Do I need GitHub? No. FlutterGo's cloud builds, signs and uploads your Android app. Only App Store deploys use GitHub Actions.
Do I need Android Studio or a local SDK? No. Everything builds on FlutterGo's build machine.
Do I still need a service-account key? No. Click Connect Google Play and sign in with Google instead. The service-account key stays available under Use a service-account key instead if you prefer it.
Where are my credentials stored? FlutterGo saves them encrypted with your project, so the wizard is filled in next time. They are used for your deploys only, never shown in your browser again, and never pushed to GitHub.
What if I lose my keystore? FlutterGo cannot recover it, so keep the signing backup safe (for example in a password manager). For apps that use Play App Signing, the Play Console account owner can ask Google to reset the upload key.
Can I ship Android and iOS at the same time? Yes, as two deploys. Start Google Play on its tab, then switch to the App Store tab and start that one. They run side by side, and one failing never stops the other. There is no single "both stores" deploy.
Can I download the app bundle? Only from a failed Google Play deploy, for the first upload by hand. To install your app on an Android phone, use Build APK in Ship. See Preview, run & build.
Can I change the package name later? You can edit it in the wizard, and FlutterGo writes it into your project. But once your app is on Google Play, its package name can't change, so choose it carefully before the first release.