Firebase / FCM setup
The FCM doorbell has two sides, each with its own credential:
- The server sends wake messages → it needs a service-account key (secret).
- The agent receives them → it needs
google-services.json(not secret) + thegoogle-servicesGradle plugin.
Both are optional for basic development: with neither configured, the server logs FCM doorbell: NOT configured, ring() is a no-op, and agents simply sync over HTTP on their normal schedule. You only need this to get push wake-ups.
Server: the service-account key
Doorbell (Doorbell.kt) resolves a credential in this order:
- Application Default Credentials — the
GOOGLE_APPLICATION_CREDENTIALSenvironment variable (or a GCP runtime). This is the recommended path. - A local key file, by trying these relative paths in turn:
firebase-service-account.jsonserver/firebase-service-account.json../server/firebase-service-account.json
Multiple candidates exist because the working directory depends on the launcher:
:server:runruns from theserver/module directory, whilejava -jarruns from wherever you invoke it.
Generate the key
Firebase console → Project settings → Service accounts → Generate new private key. Save the JSON as server/firebase-service-account.json, or point GOOGLE_APPLICATION_CREDENTIALS at it.
Never commit this file. It’s a private key.
.gitignorealready excludes**/firebase-service-account.jsonand*-service-account.json. Don’t paste its contents anywhere, including into docs or issues.
Verify
Start the server and look for the boot log:
FCM doorbell: ready — policy changes will wake devices via push.
If you instead see NOT configured, the credential wasn’t found (or failed to initialize — any failure degrades to no-op by design, so the server never 500s on the doorbell).
Agent: google-services.json + the plugin
The agent needs Firebase client config:
agent/google-services.json— downloaded from the Firebase console for the agent’s application id (com.arganaemre.mdmcore). It’s not secret and is committed (unlike the service-account key). Thegoogle-servicesplugin processes it at build time into Firebase config resources.- Gradle wiring in
agent/build.gradle.kts: thecom.google.gms.google-servicesplugin, the Firebase BoM (which pins versions), andfirebase-messaging(unversioned — the BoM controls it). Versions: development.md.
If google-services.json is missing, the agent build fails — the plugin requires it.
Emulator requirements
Live FCM needs Google Play services, which means an emulator created from a “Google APIs” system image (not a bare AOSP image).
This dovetails neatly with Device Owner: set-device-owner requires a device with no account added — and a Google APIs image with no account signed in satisfies both requirements at once. So: a fresh Google APIs emulator, no account, is the sweet spot for end-to-end testing.
Quick checklist
agent/google-services.jsonpresent (agent builds).- Service-account key at
server/firebase-service-account.jsonorGOOGLE_APPLICATION_CREDENTIALSset (server logsFCM doorbell: ready). - Emulator from a Google APIs image, no account signed in.
- Device Owner set (see agent.md).
Without the first two, everything still works — just without push. See troubleshooting.md when the doorbell rings but nothing happens.