Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 2x 2x 2x 2x 2x 1x 2x 2x 4x 4x 4x 4x 1x 3x 3x 3x 4x 2x 1x 2x 1x 1x | import { getApps, initializeApp } from "firebase-admin/app";
import { FieldValue, getFirestore } from "firebase-admin/firestore";
import { onDocumentWritten } from "firebase-functions/firestore";
import { logger } from "firebase-functions";
if (getApps().length === 0) {
initializeApp();
}
const db = getFirestore();
/**
* Server-authoritative reveal for the daily question.
*
* Each partner writes their own answer to `.../pulses/{pulseId}/answers/{uid}`,
* which (per security rules) only they can read. When BOTH members have
* answered, this trigger copies the answers into the parent pulse's `revealed`
* map — the only place either partner can read the other's answer. There is no
* client-side unlock (decision record §3).
*/
export const revealPulse = onDocumentWritten(
{
// Must match the Firestore database region (europe-west2) for the Eventarc trigger.
document: "couples/{coupleId}/pulses/{pulseId}/answers/{answerUid}",
region: "europe-west2",
},
async (event) => {
const { coupleId, pulseId } = event.params;
const pulseRef = db.doc(`couples/${coupleId}/pulses/${pulseId}`);
const [coupleSnap, answersSnap, pulseSnap] = await Promise.all([
db.doc(`couples/${coupleId}`).get(),
pulseRef.collection("answers").get(),
pulseRef.get(),
]);
if (pulseSnap.get("revealedAt")) {
return; // already revealed; nothing to do
}
const members: string[] = coupleSnap.get("members") ?? [];
if (members.length < 2) return;
const answered = new Set(answersSnap.docs.map((d) => d.id));
const bothAnswered = members.every((m) => answered.has(m));
if (!bothAnswered) return;
const revealed = Object.fromEntries(
answersSnap.docs.map((d) => [d.id, d.get("text") ?? null]),
);
await pulseRef.set(
{ revealed, revealedAt: FieldValue.serverTimestamp() },
{ merge: true },
);
logger.info(`Revealed pulse ${pulseId} for couple ${coupleId}`);
},
);
|