Turning on push notifications¶
Push is the trigger for the weekly loop, and on Android it does not work on its own: notifications are delivered by Firebase Cloud Messaging, and Google requires a Firebase project of your own. Without one the app registers no token and the error is unmistakable:
Nothing in this repository can supply that. It is account work, done once — and
it has been done for this project: Firebase project vlogroulette-8dbba,
verified end to end by an Expo delivery receipt. What follows is the record of
how, for whoever has to do it again on a different account.
Android¶
1. A Firebase project. At https://console.firebase.google.com, create a
project — analytics can be declined — then add an Android app to it with
package name com.vlogroulette.app. It has to match android.package in
app.json exactly; Google matches on it and says nothing useful when it does
not.
2. google-services.json. Download it from that Android app's settings and
put it at mobile/google-services.json. It is gitignored, and app.config.js
picks it up only when it exists, so nobody else's build breaks for want of it.
Being gitignored has a consequence that is easy to miss: EAS builds from the files it uploads, and an uncommitted file is not among them. It warns —
File specified via "android.googleServicesFile" ... is not checked in to your
repository and won't be uploaded to the builder
— and then builds anyway, producing an APK with no Firebase config at all, which fails at runtime with the error at the top of this page. So the file has to be given to EAS separately, once:
npx eas-cli env:set --name GOOGLE_SERVICES_JSON --type file \
--value ./google-services.json --visibility secret --scope project \
--environment development --environment preview --environment production
app.config.js prefers the path EAS materialises it at and falls back to the
local copy, so the same config works on the builder and on your machine. Note
that the warning still appears locally, where the real file does exist and is
still untracked; on the builder the environment variable is what gets used.
3. Give Expo permission to send. Expo's servers do the sending, so they need credentials for your Firebase project:
- In Firebase: Project settings → Service accounts → Generate new private key. That downloads a JSON file.
- Then, from
mobile/:
Choose Android → the development profile → Google Service Account → Manage your Google Service Account Key for Push Notifications (FCM V1) → Set up ... → give it the path to the JSON you just downloaded.
Do not take the Push Notifications (FCM Legacy) entry, which sits above it in the same menu. Google shut that API down in 2024 and it cannot deliver anything.
Delete the downloaded key afterwards. It can send notifications to your project, it now lives in EAS, and Firebase will mint another whenever one is needed.
4. Rebuild. google-services.json is baked into the binary, so this is one
of the changes that needs a new build rather than a reload:
5. Check it. Open the app on the circles screen — that is where the token is registered — and then:
backend/.venv/bin/python scripts/push_check.py \
--api http://<lan-ip>:8000 --email <you> --password <yours>
It walks the chain and names the broken link: backend not configured to send, no token registered, or Expo refusing the send. On success a notification arrives.
The backend also has to be started with PUSH_BACKEND=expo; the default is a
no-op that logs instead of sending, which is right for development and looks
identical to working.
iOS¶
Different mechanism, and not set up: Apple delivers through APNs, which needs a
paid Apple Developer account. eas credentials handles the key once that
account exists. Worth doing at the same time as everything else iOS needs, not
before.
What can go wrong afterwards¶
- The token changes. Reinstalling or clearing the app's data issues a new one; the app re-registers on the circles screen, and the server keeps the latest.
- Expo answers 200 and still refuses. The verdict is inside the body, not
the status.
send_nowreads it, which is why the check reportsDeviceNotRegisteredrather than success. - Nobody notices it broke. Sending is fire-and-forget by design so a failed push cannot stop a vlog publishing. The registration warning on the circle list is the counterweight.