Tuesday, September 29, 2026

How to Publish a Lovable AI App to the Google Play Store (Step-by-Step .aab Guide)

#How to Publish a Lovable or Emergent AI App to the Google Play Store (Step-by-Step `.aab` Guide)


Building a App with AI vibe-coding platforms like 'Lovable' and 'Emergent' feels effortless until it is time to launch on our mobile. You can prompt a full user interface, connect database, and test your features in a browser.

 However, when you are ready to publish your app to the "Google Play Store", there is no platform offers a one-click "Publish to Google Play" button.

When I finished building my own web app using React and Firebase, I realized that the Google Play Console doesn't accept live web URLs or GitHub links.

Google Play Console strictly requires a cryptographically signed "Android App Bundle". Because Lovable and Emergent generate fundamentally different underlying codebases, the tool you use to compile that "aab" file depends entirely on which platform built your app.

"Lovable"  generates a browser-based "React + Vite + Tailwind CSS" web application. To publish it on Android, you must wrap your compiled 'dist' folder inside a native Android WebView container using 'Ionic Capacitor' and Android Studio.

"Emergent" supports dedicated mobile agent workflows built on "React Native and Expo". Instead of wrapping a website, you compile the project directly into a native Android bundle in the cloud using "Expo Application Services (EAS)".

#part 1 : Converting a Lovable Web App to an Android 'aab' with Capacitor "Lovable" generates a standard "React + Vite + Tailwind CSS" single-page web application, you cannot upload its raw source code directly to the Google Play Console. Instead, you need to wrap that web build inside a native Android runtime using "Ionic Capacitor". Capacitor packages your static HTML, CSS, and JavaScript files into a native Android WebView while giving your app full access to native device APIs.


## Step 1: Sync Your Lovable Project to GitHub


Open your project inside the Lovable editor and click the "GitHub" icon in the top navigation bar. Connect your GitHub account, authorize Lovable to create a new repository, and push your latest commits. Once your code is on GitHub, you have full local control without burning any more AI prompts.


## Step 2: Clone the Repo and Install Capacitor Locally


Open your terminal (or VS Code integrated terminal), clone your new repository, and install the project dependencies. Before adding Capacitor, run a production build to verify that Vite generates the "dist" folder without any TypeScript or bundling errors.

Code..

# 1. Clone your exported Lovable repository

git clone https://github.com/my-username/XYZ-lovable-app.git

cd XYZ-lovable-app


# 2. Install dependencies and compile the production web folder (dist)

npm install

npm run build


# 3. Install Capacitor Core, CLI, and the Android platform package

npm install @capacitor/core @capacitor/cli @capacitor/android


# 4. Initialize Capacitor (replace with your App Name and unique Package ID)

npx cap init "YourxyzAppName" "com.yourxyzcompany.appname" --web-dir dist


## Step 3: Generate and Sync the Native Android Project

With your `"Capacitor.config.ts" (or '.json') file initialized, generate the native Android project folder and copy your compiled 'dist' assets into the Android source tree


Code..

# Create the native /android directory in your project root

npx cap add android


# Copy your Vite 'dist' build into android/app/src/main/assets/public

npx cap sync android


Every time you make a UI change in React and run `npm run build`, you must run `npx cap sync android` afterward so the native Android project receives your updated web files.


## Step 4: Compile the Signed `.aab` File in Android Studio


Launch your native project directly in Android Studio by running


Code.. 

npx cap open android


Wait two to three minutes for **Gradle** to finish indexing and downloading the required Android SDK build tools. Once the bottom status bar shows that Gradle sync is complete, package your app for the Play Store:

1. In the top menu bar of Android Studio, select "Build", then "Generate Signed Bundle / APK".

2. Select "Android App Bundle" and click "Next".

3. Under the "Key store path" field, click "Create new..." to generate your upload signing key ('.jks'file). Save this file in a secure folder outside your public GitHub repository and write down your keystore password—if you lose this key, you will not be able to push future updates to your app on the Play Store.

4. Select the "release" build variant and click "Create".


Within a minute, Android Studio will output your signed 'app-release.aab' file inside 'android/app/release/'.


## Fixing Common Bugs: Blank White Screens & Broken Firebase Auth


Most AI app tutorials stop right after generating the '.aab' file. However, the first time you install your wrapped Lovable app onto a real Android phone, you will likely run into two infamous bugs: a completely blank white screen on launch, or a Google Sign-In button that crashes immediately.

## Bug 1: The Blank White Screen on Launch (Vite Relative Path Fix)


When your React app runs inside a browser, a web server resolves root paths like '/assets/index.js' automatically. Inside an Android WebView wrapper, your files are loaded locally from the device's internal asset directory. When Vite defaults to absolute '/' paths, the Android WebView looks at the root of the Android file system, fails to find your JavaScript bundle, and renders a blank white screen.


To fix this permanently, open 'vite.config.ts' in your project root and add 'base: './' inside the 'defineConfig' block:


****typescript

import { defineConfig } from "vite";

import react from "@vitejs/plugin-react-swc";

import path from "path";


export default defineConfig({

  base: "./", // Forces relative asset paths for Capacitor WebView

  plugins: [react()],

  resolve: {

    alias: {

      "@": path.resolve(__dirname, "./src"),

    },

  },

});


```


After saving 'vite.config.ts', run 'npm run build' followed by 'npx cap sync android' to push the corrected asset paths into your Android build.


### Bug 2: Firebase Auth & Google OAuth Failing Inside the Android WebView


If your Lovable or Emergent app uses "Firebase Authentication"  with Google Sign-In, the standard web `signInWithPopup(auth, provider)` function will almost always fail inside an Android app. Either the popup window closes immediately without returning a token, or Google blocks the login request with an 'Error 403: disallowed_useragent` warning because Google OAuth prohibits embedded WebViews from handling web popups.


To make Firebase Google Sign-In work reliably on Android, complete these three configuration steps:

1. **Register Your Android App & SHA-1 Key in Firebase:** Open your **Firebase Console**, go to **Project Settings**, and click **Add app** to register an Android target using your exact Capacitor package ID ('com.yourcompany.appname'). Next, generate your SHA-1 signing certificate fingerprint by running this command inside your `/android` folder:


Code...

cd android

./gradlew signingReport


Copy the `SHA-1` string from the terminal output, paste it into your Firebase Android app settings, and download the generated 'google-services.json' file directly into your 'android/app/' folder.


2. **Whitelist Capacitor Localhost in Firebase:** Go to **Firebase Console**, select **Authentication**, open the **Settings** tab, and click **Authorized domains**. Ensure `localhost` is listed so email/password and token refreshes are not rejected by the Capacitor local server.


3. "Bridge Native Auth to the Firebase Web SDK: Instead of relying on browser popups on mobile devices, install @capacitor-firebase/authentication and use Capacitor.getPlatform() to detect when the app is running on Android. Trigger the native Android account picker first, grab the returned Google ID token, and pass it into Firebase's signInWithCredential() method:

TypeScript

import { Capacitor } from "@capacitor/core";

import { FirebaseAuthentication } from "@capacitor-firebase/authentication";

import { GoogleAuthProvider, signInWithCredential, signInWithPopup } from "firebase/auth";

import { auth } from "./firebaseConfig";


export const handleGoogleLogin = async () => {

  if (Capacitor.isNativePlatform()) {

    // 1. Trigger the native Android Google Account picker

    const result = await FirebaseAuthentication.signInWithGoogle();

    

    // 2. Pass the native ID token into the Firebase JS SDK

    const credential = GoogleAuthProvider.credential(result.credential?.idToken);

    return await signInWithCredential(auth, credential);

  } else {

    // Fallback for standard web browser testing

    const provider = new GoogleAuthProvider();

    return await signInWithPopup(auth, provider);

  }

};

 #3: Delete this line and upload a screenshot of your Firebase Console Project Settings or Authentication screen here. Blur out any private API keys.]


Passing Google Play's "12 Testers for 14 Days" Rule

Generating your .aab file is only half the battle. If you registered a personal Google Play Developer account (after paying the one-time $25 registration fee), the Production release button will be locked.

While many older tutorials still claim you need 20 testers, Google updated its policy to require at least 12 testers opted in continuously for 14 consecutive days in a Closed Testing track before you can apply for production access. If a single tester opts out on Day 11 and drops your active count to 11, your 14-day clock resets to zero.


Follow this exact four-step checklist to pass the review on your first attempt:


Use the "Closed Testing" Track (Not Internal Testing): Google's Internal Testing track is great for quick previews, but it does not count toward the 14-day requirement. Navigate to Test and release, select Testing, open Closed testing, and click Manage track next to the Alpha track to upload your .aab file.


Recruit a Safety Buffer of 16 to 20 Testers: Never start your test with exactly 12 people. Create a Google Group for your testers or collect 16 to 20 Gmail addresses from communities like r/AndroidClosedTesting on Reddit where indie developers test each other's apps for free. Having 18 opted-in users guarantees that if three people uninstall your app mid-week, your active count stays safely above the 12-tester floor.


Push at Least One Update During the 14 Days: Do not let your app sit untouched for two weeks. Around Day 6 or Day 7, change a small UI detail or fix a minor bug, increment the versionCode in your build.gradle (or app.json), and upload a new .aab release to the Closed Testing track. Updating the build does not reset your 14-day timer, and it proves to Google's human reviewers that you are actively iterating on tester feedback.


Answer the Three-Part Production Questionnaire Carefully: Once the Play Console dashboard confirms you have completed 14 consecutive days with 12 or more testers, the Apply for production button unlocks. You will have to fill out three forms (About your closed test, About your app/game, and About your production readiness). Write detailed, specific answers explaining how you collected feedback (for example, via a Google Form or GitHub Issues) and list the exact UI or authentication fixes you pushed during the test window


FOR EMERGENT APP YOU CAN VISIT NEXT BLOG

No comments:

Post a Comment

How to Integrate Stripe Payments into a Lovable React App Without a Paid Backend (2026 Guide)

#How to Integrate Stripe Payments into a Lovable React App Without a Paid Backend (2026 Guide) Building a sleek SaaS dashboard or digital st...