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.
| 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. |
fortheease@gmail.com (Play Console →
Settings → Developer account → Developer page)..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.
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.
# 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):
./gradlew signingReport)keytool -list -v -keystore bitebox-release.keystore -alias bitebox)Then re-download google-services.json (it embeds the fingerprints) and replace
the copy in app/.
app/build.gradlenow fails the release build ifgoogle-services.jsonis missing or the release keystore is not configured inlocal.properties, so a Firebase-less AAB can no longer be uploaded by accident.
./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.
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.
BITe BoxThis drops you into the app’s Dashboard, which tracks the remaining setup tasks across these sections (do them in roughly this order):
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 andicon_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#FF7A1Athese 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 vectoric_*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.pngis 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.
The public URL that must go in the Privacy Policy step and inside the app is the GitHub Pages URL:
https://nickkerdroid.github.io/test/privacy-policy.html
To publish it:
main (or the branch you merge to), folder = / (root).The standalone page is /privacy-policy.html at the repo root; the Markdown
source is docs/PRIVACY_POLICY.md.
Google rejects apps whose privacy policy link is broken, behind a login, or a placeholder. Confirm the URL resolves before submitting.
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?”
Answer the IARC questionnaire per docs/CONTENT_RATING.md. The expected
rating is Everyone. All violence/profanity/gambling questions are No.
The app is gated to @bitmesra.ac.in accounts, so for the reviewer add a
demo credential entry:
@bitmesra.ac.in Google account you own.@bitmesra.ac.in. The email domain is hard‑checked; other domains cannot sign
in by design (campus‑only access).”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.
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.
@bitmesra.ac.in gate already makes it
irrelevant to children).1.0.0.docs/STORE_LISTING.md.app/build/outputs/bundle/release/app-release.aab.| 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 |
versionCode (e.g. to 2) and versionName
(e.g. 1.0.1) in app/build.gradle before rebuilding — Play rejects an upload
whose versionCode is not greater than the last production version.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