BITe-Box

Publishing BITe Box to the Google Play Store — Complete Guide

This is the end‑to‑end playbook for shipping BITe Box (info.fortheease.bitebox, v1.0) to the Google Play Store. It is written so you can run it top‑to‑bottom. Every file referenced here has already been generated in this repository.

Everything below assumes the four choices you locked in: Publisher = ForTheEase, support email = fortheease@gmail.com, privacy policy hosted on GitHub Pages, and AdMob live ads = yes.


0. What you need before you start

Item Detail
A Google account Becomes your Play Console owner account.
~₹900 (US $25) One‑time Play Console registration fee.
Government photo ID + a payment card Used by Google for developer identity verification (can take 1–3 days).
A real Android device or emulator To smoke‑test the signed build.
Your own google-services.json For Firebase Auth. See FIREBASE_SETUP.md.
Your own AdMob app ID + banner unit ID In local.properties. See ADMOB_SETUP.md.

1. Create & verify the Play Console account

  1. Go to https://play.google.com/console and sign in.
  2. Choose account type Personal (publisher = ForTheEase).
  3. Pay the one‑time $25 registration fee.
  4. Complete Developer identity verification: upload a government photo ID and add a payment card for the small verification charge. Approvals take 1–3 days and you cannot publish until this passes. Keep the developer name exactly ForTheEase — it shows on the store and in this app’s metadata.
  5. Set the public contact email to fortheease@gmail.com (Play Console → Settings → Developer account → Developer page).

2. Produce a signed App Bundle (.aab)

Google Play requires Android App Bundles for new apps (APKs are not accepted for first publish). This repo is already wired to sign the release build.

2a. Generate your release (upload) key — one time

bash scripts/generate-keystore.sh

It creates bitebox-release.keystore at the repo root and prints four lines. Paste them into local.properties (git‑ignored):

releaseStoreFile=../bitebox-release.keystore
releaseStorePassword=<printed by the script>
releaseKeyAlias=bitebox
releaseKeyPassword=<printed by the script>

Back up the .keystore file and both passwords to a password manager / cloud drive. With Play App Signing you can reset a lost upload key, but a backup is still far less painful.

2b. Configure Firebase & AdMob for production (not test IDs)

# local.properties
admob.appId=ca-app-pub-XXXXXXXXXXXXXXXX~XXXXXXXXXX
admob.bannerAdUnitId=ca-app-pub-XXXXXXXXXXXXXXXX/XXXXXXXXXX

Drop your real google-services.json into app/. (See FIREBASE_SETUP.md.) Shipment with the Google test AdMob IDs is the single most common cause of AdMob account suspension — confirm the IDs are your live ones before building.

Register every signing certificate in Firebase (this is the step that makes Google Sign-In work in production):

Then re-download google-services.json (it embeds the fingerprints) and replace the copy in app/.

app/build.gradle now fails the release build if google-services.json is missing or the release keystore is not configured in local.properties, so a Firebase-less AAB can no longer be uploaded by accident.

2c. Build the bundle

./gradlew :app:bundleRelease

Output:

app/build/outputs/bundle/release/app-release.aab
# Confirm the bundle is signed and inspect the signer:
keytool -printcert -jarfile app/build/outputs/bundle/release/app-release.aab

You should see a certificate whose Owner is CN=ForTheEase.

2e. Test the release build locally (install on a device)

A bundle can’t be installed directly; use Google’s bundletool to produce an APK for a connected device:

bundletool build-apks --bundle=app/build/outputs/bundle/release/app-release.aab \
  --output=app-release.apks --mode=universal
bundletool install-apks --apks=app-release.apks

Install bundletool from https://github.com/google/bundletool/releases. Smoke‑test sign‑in, the cart, a WhatsApp checkout, and that a live (not test) banner appears.


3. Create the app in Play Console

  1. Play Console → All apps → Create app.
  2. App name: BITe Box
  3. Default language: English (United States)
  4. App type: App
  5. Pricing: Free
  6. Declarations: tick both policy declarations and Continue.

This drops you into the app’s Dashboard, which tracks the remaining setup tasks across these sections (do them in roughly this order):

  1. App access
  2. Ads (because AdMob is live)
  3. Content rating
  4. Target audience
  5. News app (skip — not a news app)
  6. Data safety
  7. Government apps (skip)
  8. Financial features (skip — ordering + payment happen in WhatsApp)
  9. Privacy Policy
  10. App content / main store listing

4. Main store listing

Use the copy in docs/STORE_LISTING.md. Upload the graphics in store/:

Asset File Spec
App icon store/icon_512.png 512×512 PNG, 32‑bit, no alpha
Feature graphic store/feature_graphic_1024x500.png 1024×500 PNG/JPG
Phone screenshots store/screenshot_*.png min 2 (≤8), 16:9 or 9:16, each side ≥320px

Important: the generated phone screenshots are branded marketing mockups. For the strongest listing (and to satisfy reviewers), replace them with real screenshots captured from the signed release build (see §2e). The mockups are a safe fallback that already meet the dimension requirements.

Stale since the 2026-09-28 UI redesign: every graphic in store/ (the four screenshots, the feature graphic and icon_512.png) was produced for the pre-redesign app UI. The palette has since been back to its original dark + tangerine values (#F97316, not the #FF7A1A these assets were drawn with), but the structure the assets show is the old one — emoji icons, gradient buttons, pill chrome — while the shipped app now has the vector ic_* icon set, flat cards with hairline dividers and inline quantity steppers. So these assets no longer match the product. Refresh all of them from a device running the current build before the next store release — until then the listing advertises a design the app no longer has. res/drawable/icon_512.png is the full-colour master and is the brand art the top bar and sign-in lockup use in-app again, so it is the base to recapture the icon from.


5. Privacy Policy

Google rejects apps whose privacy policy link is broken, behind a login, or a placeholder. Confirm the URL resolves before submitting.


6. Data safety

Fill the Data safety form exactly as documented in docs/DATA_SAFETY.md. The headline points (because AdMob is live and Firebase Auth is used):

Mark “Yes” to “Is your app’s advertising ID used for advertising purposes?”


7. Content rating

Answer the IARC questionnaire per docs/CONTENT_RATING.md. The expected rating is Everyone. All violence/profanity/gambling questions are No.


8. App access

The app is gated to @bitmesra.ac.in accounts, so for the reviewer add a demo credential entry:

If you cannot share a campus account, describe the domain gate in the instructions and provide the order flow that reviewers can otherwise still browse.


9. Ads declaration

Because AdMob serves real ads, answer “Yes, my app contains ads” in the Ads step. Confirm your AdMob ad units are linked/registered; Google cross‑checks this.


10. Target audience


11. Release (Production rollout)

  1. Production → Create release.
  2. Release name: 1.0.0.
  3. Release notes (English): use the short note from docs/STORE_LISTING.md.
  4. Upload app/build/outputs/bundle/release/app-release.aab.
  5. Release notes and review the rollout stages (Staging 100% is fine for v1).
  6. Review release → Start rollout to Production.

Review timelines


12. Common rejection reasons (and how we’ve already handled them)

Risk Status in this repo
Broken/placeholder privacy policy GitHub‑Pages HTML generated; URL in §5
Missing Data Safety advertising‑ID declaration Documented in docs/DATA_SAFETY.md
Serving test AdMob IDs in production Warning in app/build.gradle; configure live IDs (§2b)
Release built without google-services.json (login dead on Play Store) Hard build guard in app/build.gradle (§2b)
Play App Signing SHA‑1 missing from Firebase (Google Sign‑In fails on store installs) Documented in §2b and FIREBASE_SETUP.md
Not targeting a recent API targetSdk 36 ✅
64‑bit / missing signing Signing config in app/build.gradle ✅
No contact email fortheease@gmail.com set ✅
Missing app access credentials Documented in §8

13. After launch


File index for this submission

app/proguard-rules.pro              # ProGuard rules (was missing — would break release build)
app/build.gradle                    # + signingConfigs.release for the upload key
scripts/generate-keystore.sh        # One-time release-key generator
privacy-policy.html                 # Hosted privacy policy for GitHub Pages
docs/PRIVACY_POLICY.md              # Privacy-policy source
docs/STORE_LISTING.md               # Title, short/full descriptions, release notes
docs/DATA_SAFETY.md                 # Exact Data Safety answers
docs/CONTENT_RATING.md              # Exact IARC questionnaire answers
store/icon_512.png                  # 512×512 high-res icon
store/feature_graphic_1024x500.png  # Feature graphic
store/screenshot_*.png              # Phone screenshots