Files
oott/push_relay/src/index.ts
T
rzuastiandClaude Opus 4.8 d81eba3b37 Deploy push relay: dev-shell tooling, real relay URL, /health route
- flake.nix: add nodejs_22, firebase-tools, and google-cloud-sdk to the dev
  shell so the relay can be tested, built, deployed, and administered locally
- backend settings: point default_relay_url at the deployed relay
- rename the relay liveness route /healthz -> /health: Google Front End
  reserves /healthz and returns its own 404 before the request reaches Cloud
  Run, so the probe was unreachable (verified live; /v1/push and the FCM path
  work end-to-end)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 14:00:09 -04:00

31 lines
1.3 KiB
TypeScript

import { initializeApp } from "firebase-admin/app";
import { getFirestore } from "firebase-admin/firestore";
import { getMessaging } from "firebase-admin/messaging";
import { onRequest } from "firebase-functions/v2/https";
import { createApp } from "./app";
import { createFirestoreRateLimitStore, type FirestoreLike } from "./rateLimit";
import type { MessengerLike, TokenMessage } from "./push";
// One Admin SDK app per function instance. It authenticates to FCM via the function's runtime
// service account — there is no service-account JSON to manage, store, or rotate (Google keeps the
// secret).
initializeApp();
// Adapt the Admin Messaging API to the small MessengerLike surface the handler depends on.
const messenger: MessengerLike = {
sendEach(messages: TokenMessage[]) {
return getMessaging().sendEach(messages);
},
};
const rateLimitStore = createFirestoreRateLimitStore(
getFirestore() as unknown as FirestoreLike,
);
const app = createApp({ messenger, rateLimitStore });
// Single HTTP function hosting both routes (POST /v1/push, GET /health). Scales to zero, so there
// is no idle cost and no server/OS to patch; the platform provides TLS and a stable HTTPS URL.
export const relay = onRequest({ region: "us-central1", maxInstances: 10 }, app);