From 4c077c4d7c2dfe6505a48bcf6367c081fa6da090 Mon Sep 17 00:00:00 2001 From: null Date: Wed, 8 Jul 2026 00:08:18 -0500 Subject: [PATCH] refactor(functions): B6c split game part-finished trigger + reorder reads (#11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the single broad onGamePartFinished (couples/{coupleId}/{gameType}/{sessionId} wildcard, which fired a no-op invocation on every write to ANY couple subcollection) into four narrow, explicitly-pathed triggers sharing one handler: onThisOrThatPartFinished, onWheelPartFinished, onHowWellPartFinished, onDesireSyncPartFinished. Behavior is identical for the four game collections; the spurious invocations for messages/reactions/etc. are eliminated. (Background triggers have no client name dependency; the old export is dropped and the four deploy fresh — the deploy runbook already accounts for this.) onGameSessionUpdate: move the `!change.after.exists` deletion guard ABOVE its four reads (session/couple/userA/userB) so a delete/no-op event returns before doing any reads. The delicate exactly-once claim-flag logic is otherwise untouched. Build clean; 70 tests green. Discovery loads all four split triggers as v2 in us-central1 (36 functions total); old onGamePartFinished gone. dist rebuilt. Co-Authored-By: Claude Opus 4.8 --- functions/dist/games/onGameSessionUpdate.js | 24 ++-- .../dist/games/onGameSessionUpdate.js.map | 2 +- functions/dist/index.js | 7 +- functions/dist/index.js.map | 2 +- functions/src/games/onGameSessionUpdate.ts | 108 +++++++++++------- functions/src/index.ts | 8 +- 6 files changed, 92 insertions(+), 59 deletions(-) diff --git a/functions/dist/games/onGameSessionUpdate.js b/functions/dist/games/onGameSessionUpdate.js index c0b7b2b5..4d5be6f2 100644 --- a/functions/dist/games/onGameSessionUpdate.js +++ b/functions/dist/games/onGameSessionUpdate.js @@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -exports.onGamePartFinished = exports.onGameSessionUpdate = void 0; +exports.onDesireSyncPartFinished = exports.onHowWellPartFinished = exports.onWheelPartFinished = exports.onThisOrThatPartFinished = exports.onGameSessionUpdate = void 0; const admin = __importStar(require("firebase-admin")); const firestore_1 = require("firebase-functions/v2/firestore"); const quietHours_1 = require("../notifications/quietHours"); @@ -55,6 +55,8 @@ exports.onGameSessionUpdate = (0, firestore_1.onDocumentWritten)('couples/{coupl const change = event.data; if (!change) return; + if (!change.after.exists) + return; // deletion — nothing to notify (skip the four reads below) const db = admin.firestore(); const messaging = admin.messaging(); // Get the session document @@ -89,8 +91,6 @@ exports.onGameSessionUpdate = (0, firestore_1.onDocumentWritten)('couples/{coupl // M-001: per-recipient quiet-hours lookup ("no notifications" promise). Fail-open. const dataFor = (uid) => (uid === partnerA ? userA.data() : userB.data()); const currentData = (_e = change.after.data()) !== null && _e !== void 0 ? _e : {}; - if (!change.after.exists) - return; // deletion — nothing to notify const status = currentData.status; const sessionRef = db.collection('couples').doc(coupleId).collection('sessions').doc(sessionId); // Detect start/finish from the session's CURRENT state + a one-time flag, NOT from the @@ -203,14 +203,14 @@ exports.onGameSessionUpdate = (0, firestore_1.onDocumentWritten)('couples/{coupl * PARTNER_COMPLETED_PART client route already exists; this is the trigger that finally emits it. * * Path: couples/{coupleId}/{gameType}/{sessionId} (answer doc; same id as the session doc). + * + * Deployed as four narrow, explicitly-pathed triggers (one per async-game collection) sharing the + * handler below, rather than one broad `{gameType}` wildcard — the wildcard fired a (no-op) + * invocation on every write to ANY couple subcollection (messages, reactions, …); the narrow paths + * only fire for the four game collections. */ -const ASYNC_GAME_COLLECTIONS = ['this_or_that', 'wheel', 'how_well', 'desire_sync']; -exports.onGamePartFinished = (0, firestore_1.onDocumentWritten)('couples/{coupleId}/{gameType}/{sessionId}', async (event) => { +async function handleGamePartFinished(coupleId, gameType, sessionId, change) { var _a, _b, _c, _d, _e; - const { coupleId, gameType, sessionId } = event.params; - if (!ASYNC_GAME_COLLECTIONS.includes(gameType)) - return; // ignore messages/reactions/etc. - const change = event.data; if (!(change === null || change === void 0 ? void 0 : change.after.exists)) return; const answers = ((_b = (_a = change.after.data()) === null || _a === void 0 ? void 0 : _a.answers) !== null && _b !== void 0 ? _b : {}); @@ -247,7 +247,11 @@ exports.onGamePartFinished = (0, firestore_1.onDocumentWritten)('couples/{couple const finisherName = 'Your partner'; // displayName is E2EE; the app shows the real name in-app const finisherAvatar = (_e = finisher.data()) === null || _e === void 0 ? void 0 : _e.photoUrl; await notifyPartner(db, messaging, recipient, finisherName, gameType, 'partner_completed_part', yourTurnBody(gameType), coupleId, finisherAvatar, sessionId); -}); +} +exports.onThisOrThatPartFinished = (0, firestore_1.onDocumentWritten)('couples/{coupleId}/this_or_that/{sessionId}', (event) => handleGamePartFinished(event.params.coupleId, 'this_or_that', event.params.sessionId, event.data)); +exports.onWheelPartFinished = (0, firestore_1.onDocumentWritten)('couples/{coupleId}/wheel/{sessionId}', (event) => handleGamePartFinished(event.params.coupleId, 'wheel', event.params.sessionId, event.data)); +exports.onHowWellPartFinished = (0, firestore_1.onDocumentWritten)('couples/{coupleId}/how_well/{sessionId}', (event) => handleGamePartFinished(event.params.coupleId, 'how_well', event.params.sessionId, event.data)); +exports.onDesireSyncPartFinished = (0, firestore_1.onDocumentWritten)('couples/{coupleId}/desire_sync/{sessionId}', (event) => handleGamePartFinished(event.params.coupleId, 'desire_sync', event.params.sessionId, event.data)); /** * Per-game body for the "your turn" (partner_completed_part) push — mirrors the client banner's * YOUR_TURN copy in ui/components/GamePromptBanner.kt so foreground and background read the same. diff --git a/functions/dist/games/onGameSessionUpdate.js.map b/functions/dist/games/onGameSessionUpdate.js.map index 65c9727c..d29ac602 100644 --- a/functions/dist/games/onGameSessionUpdate.js.map +++ b/functions/dist/games/onGameSessionUpdate.js.map @@ -1 +1 @@ -{"version":3,"file":"onGameSessionUpdate.js","sourceRoot":"","sources":["../../src/games/onGameSessionUpdate.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"onGameSessionUpdate.js","sourceRoot":"","sources":["../../src/games/onGameSessionUpdate.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/functions/dist/index.js b/functions/dist/index.js index 4cf6b871..1d74c56e 100644 --- a/functions/dist/index.js +++ b/functions/dist/index.js @@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -exports.wrapReleaseKeyCallable = exports.onGamePartFinished = exports.onGameSessionUpdate = exports.onUserDelete = exports.scheduledOutcomesReminder = exports.aggregateOutcomeStats = exports.submitOutcomeCallable = exports.createInviteCallable = exports.acceptInviteCallable = exports.leaveCoupleCallable = exports.onCoupleLeave = exports.onMessageWritten = exports.onAnswerRevealed = exports.onAnswerWritten = exports.assignDailyQuestionCallable = exports.assignDailyQuestion = exports.onRestoreFulfilled = exports.onRestoreRequested = exports.onDateHistoryCreated = exports.onDateReflectionRevealed = exports.onDateReflectionWritten = exports.notifyOnDateMatch = exports.checkDeviceIntegrity = exports.sendReengagementReminder = exports.sendStreakReminder = exports.sendDailyQuestionProactiveReminder = exports.unlockDueMemoryCapsules = exports.sendChallengeDayReminders = exports.sendThinkingOfYouCallable = exports.sendGentleReminderCallable = exports.onEntitlementChanged = exports.syncEntitlement = exports.revenueCatWebhook = void 0; +exports.wrapReleaseKeyCallable = exports.onDesireSyncPartFinished = exports.onHowWellPartFinished = exports.onWheelPartFinished = exports.onThisOrThatPartFinished = exports.onGameSessionUpdate = exports.onUserDelete = exports.scheduledOutcomesReminder = exports.aggregateOutcomeStats = exports.submitOutcomeCallable = exports.createInviteCallable = exports.acceptInviteCallable = exports.leaveCoupleCallable = exports.onCoupleLeave = exports.onMessageWritten = exports.onAnswerRevealed = exports.onAnswerWritten = exports.assignDailyQuestionCallable = exports.assignDailyQuestion = exports.onRestoreFulfilled = exports.onRestoreRequested = exports.onDateHistoryCreated = exports.onDateReflectionRevealed = exports.onDateReflectionWritten = exports.notifyOnDateMatch = exports.checkDeviceIntegrity = exports.sendReengagementReminder = exports.sendStreakReminder = exports.sendDailyQuestionProactiveReminder = exports.unlockDueMemoryCapsules = exports.sendChallengeDayReminders = exports.sendThinkingOfYouCallable = exports.sendGentleReminderCallable = exports.onEntitlementChanged = exports.syncEntitlement = exports.revenueCatWebhook = void 0; // Global v2 options (region pin, instance cap) — MUST be imported before any function module so // setGlobalOptions runs before the functions below are defined. require("./options"); @@ -103,7 +103,10 @@ var onUserDelete_1 = require("./users/onUserDelete"); Object.defineProperty(exports, "onUserDelete", { enumerable: true, get: function () { return onUserDelete_1.onUserDelete; } }); var onGameSessionUpdate_1 = require("./games/onGameSessionUpdate"); Object.defineProperty(exports, "onGameSessionUpdate", { enumerable: true, get: function () { return onGameSessionUpdate_1.onGameSessionUpdate; } }); -Object.defineProperty(exports, "onGamePartFinished", { enumerable: true, get: function () { return onGameSessionUpdate_1.onGamePartFinished; } }); +Object.defineProperty(exports, "onThisOrThatPartFinished", { enumerable: true, get: function () { return onGameSessionUpdate_1.onThisOrThatPartFinished; } }); +Object.defineProperty(exports, "onWheelPartFinished", { enumerable: true, get: function () { return onGameSessionUpdate_1.onWheelPartFinished; } }); +Object.defineProperty(exports, "onHowWellPartFinished", { enumerable: true, get: function () { return onGameSessionUpdate_1.onHowWellPartFinished; } }); +Object.defineProperty(exports, "onDesireSyncPartFinished", { enumerable: true, get: function () { return onGameSessionUpdate_1.onDesireSyncPartFinished; } }); var wrapReleaseKeyCallable_1 = require("./releaseKey/wrapReleaseKeyCallable"); Object.defineProperty(exports, "wrapReleaseKeyCallable", { enumerable: true, get: function () { return wrapReleaseKeyCallable_1.wrapReleaseKeyCallable; } }); // NOTE (security review Batch 2): the unauthenticated public `health` HTTP endpoint diff --git a/functions/dist/index.js.map b/functions/dist/index.js.map index 69e1a50b..76982a4b 100644 --- a/functions/dist/index.js.map +++ b/functions/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gGAAgG;AAChG,gEAAgE;AAChE,qBAAkB;AAClB,sDAAuC;AAEvC,qEAAqE;AACrE,8EAA8E;AAC9E,gFAAgF;AAChF,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,aAAa,EAAE,CAAA;AACvB,CAAC;AAED,iEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAC1B,6DAA2D;AAAlD,kHAAA,eAAe,OAAA;AACxB,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,yFAAuF;AAA9E,wIAAA,0BAA0B,OAAA;AACnC,uFAAqF;AAA5E,sIAAA,yBAAyB,OAAA;AAClC,+DAGsC;AAFpC,0HAAA,yBAAyB,OAAA;AACzB,wHAAA,uBAAuB,OAAA;AAEzB,+EAA0F;AAAjF,2IAAA,kCAAkC,OAAA;AAC3C,iEAAmE;AAA1D,oHAAA,kBAAkB,OAAA;AAC3B,6DAAuE;AAA9D,wHAAA,wBAAwB,OAAA;AACjC,wEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,2DAA2D;AAAlD,oHAAA,iBAAiB,OAAA;AAC1B,2EAAyE;AAAhE,kIAAA,uBAAuB,OAAA;AAChC,6EAA2E;AAAlE,oIAAA,wBAAwB,OAAA;AACjC,qEAAmE;AAA1D,4HAAA,oBAAoB,OAAA;AAC7B,kEAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAC/C,uEAGwC;AAFtC,0HAAA,mBAAmB,OAAA;AACnB,kIAAA,2BAA2B,OAAA;AAE7B,+DAA6D;AAApD,kHAAA,eAAe,OAAA;AACxB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,yDAAuD;AAA9C,8GAAA,aAAa,OAAA;AACtB,qEAAmE;AAA1D,0HAAA,mBAAmB,OAAA;AAC5B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,yEAAuE;AAA9D,8HAAA,qBAAqB,OAAA;AAC9B,iEAAmE;AAA1D,0HAAA,qBAAqB,OAAA;AAC9B,iFAA+E;AAAtE,sIAAA,yBAAyB,OAAA;AAClC,qDAAmD;AAA1C,4GAAA,YAAY,OAAA;AACrB,mEAAqF;AAA5E,0HAAA,mBAAmB,OAAA;AAAE,yHAAA,kBAAkB,OAAA;AAEhD,8EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAE/B,oFAAoF;AACpF,uEAAuE;AACvE,iFAAiF;AACjF,0DAA0D"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gGAAgG;AAChG,gEAAgE;AAChE,qBAAkB;AAClB,sDAAuC;AAEvC,qEAAqE;AACrE,8EAA8E;AAC9E,gFAAgF;AAChF,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,aAAa,EAAE,CAAA;AACvB,CAAC;AAED,iEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAC1B,6DAA2D;AAAlD,kHAAA,eAAe,OAAA;AACxB,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,yFAAuF;AAA9E,wIAAA,0BAA0B,OAAA;AACnC,uFAAqF;AAA5E,sIAAA,yBAAyB,OAAA;AAClC,+DAGsC;AAFpC,0HAAA,yBAAyB,OAAA;AACzB,wHAAA,uBAAuB,OAAA;AAEzB,+EAA0F;AAAjF,2IAAA,kCAAkC,OAAA;AAC3C,iEAAmE;AAA1D,oHAAA,kBAAkB,OAAA;AAC3B,6DAAuE;AAA9D,wHAAA,wBAAwB,OAAA;AACjC,wEAAsE;AAA7D,4HAAA,oBAAoB,OAAA;AAC7B,2DAA2D;AAAlD,oHAAA,iBAAiB,OAAA;AAC1B,2EAAyE;AAAhE,kIAAA,uBAAuB,OAAA;AAChC,6EAA2E;AAAlE,oIAAA,wBAAwB,OAAA;AACjC,qEAAmE;AAA1D,4HAAA,oBAAoB,OAAA;AAC7B,kEAAoF;AAA3E,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAC/C,uEAGwC;AAFtC,0HAAA,mBAAmB,OAAA;AACnB,kIAAA,2BAA2B,OAAA;AAE7B,+DAA6D;AAApD,kHAAA,eAAe,OAAA;AACxB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,iEAA+D;AAAtD,oHAAA,gBAAgB,OAAA;AACzB,yDAAuD;AAA9C,8GAAA,aAAa,OAAA;AACtB,qEAAmE;AAA1D,0HAAA,mBAAmB,OAAA;AAC5B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,uEAAqE;AAA5D,4HAAA,oBAAoB,OAAA;AAC7B,yEAAuE;AAA9D,8HAAA,qBAAqB,OAAA;AAC9B,iEAAmE;AAA1D,0HAAA,qBAAqB,OAAA;AAC9B,iFAA+E;AAAtE,sIAAA,yBAAyB,OAAA;AAClC,qDAAmD;AAA1C,4GAAA,YAAY,OAAA;AACrB,mEAMoC;AALlC,0HAAA,mBAAmB,OAAA;AACnB,+HAAA,wBAAwB,OAAA;AACxB,0HAAA,mBAAmB,OAAA;AACnB,4HAAA,qBAAqB,OAAA;AACrB,+HAAA,wBAAwB,OAAA;AAG1B,8EAA4E;AAAnE,gIAAA,sBAAsB,OAAA;AAE/B,oFAAoF;AACpF,uEAAuE;AACvE,iFAAiF;AACjF,0DAA0D"} \ No newline at end of file diff --git a/functions/src/games/onGameSessionUpdate.ts b/functions/src/games/onGameSessionUpdate.ts index ae7cdf1c..0f2237ad 100644 --- a/functions/src/games/onGameSessionUpdate.ts +++ b/functions/src/games/onGameSessionUpdate.ts @@ -1,5 +1,5 @@ import * as admin from 'firebase-admin' -import { onDocumentWritten } from 'firebase-functions/v2/firestore' +import { onDocumentWritten, Change } from 'firebase-functions/v2/firestore' import { recipientInQuietHours } from '../notifications/quietHours' import { sendPushToUser } from '../notifications/push' import { logger } from '../log' @@ -21,6 +21,7 @@ export const onGameSessionUpdate = onDocumentWritten( const change = event.data if (!change) return + if (!change.after.exists) return // deletion — nothing to notify (skip the four reads below) const db = admin.firestore() const messaging = admin.messaging() @@ -62,7 +63,6 @@ export const onGameSessionUpdate = onDocumentWritten( const dataFor = (uid: string) => (uid === partnerA ? userA.data() : userB.data()) const currentData = change.after.data() ?? {} - if (!change.after.exists) return // deletion — nothing to notify const status = currentData.status as string | undefined const sessionRef = db.collection('couples').doc(coupleId).collection('sessions').doc(sessionId) @@ -189,54 +189,74 @@ export const onGameSessionUpdate = onDocumentWritten( * PARTNER_COMPLETED_PART client route already exists; this is the trigger that finally emits it. * * Path: couples/{coupleId}/{gameType}/{sessionId} (answer doc; same id as the session doc). + * + * Deployed as four narrow, explicitly-pathed triggers (one per async-game collection) sharing the + * handler below, rather than one broad `{gameType}` wildcard — the wildcard fired a (no-op) + * invocation on every write to ANY couple subcollection (messages, reactions, …); the narrow paths + * only fire for the four game collections. */ -const ASYNC_GAME_COLLECTIONS = ['this_or_that', 'wheel', 'how_well', 'desire_sync'] -export const onGamePartFinished = onDocumentWritten( - 'couples/{coupleId}/{gameType}/{sessionId}', - async (event) => { - const { coupleId, gameType, sessionId } = event.params - if (!ASYNC_GAME_COLLECTIONS.includes(gameType)) return // ignore messages/reactions/etc. - const change = event.data - if (!change?.after.exists) return +async function handleGamePartFinished( + coupleId: string, + gameType: string, + sessionId: string, + change: Change | undefined +): Promise { + if (!change?.after.exists) return - const answers = (change.after.data()?.answers ?? {}) as Record - const answerUids = Object.keys(answers) - // Only the FIRST finisher (exactly one answer present) nudges the partner. Zero = session just - // created; two = both done → the session flips to completed and onGameSessionUpdate sends - // partner_finished_game instead. - if (answerUids.length !== 1) return - const finisherUid = answerUids[0] + const answers = (change.after.data()?.answers ?? {}) as Record + const answerUids = Object.keys(answers) + // Only the FIRST finisher (exactly one answer present) nudges the partner. Zero = session just + // created; two = both done → the session flips to completed and onGameSessionUpdate sends + // partner_finished_game instead. + if (answerUids.length !== 1) return + const finisherUid = answerUids[0] - const db = admin.firestore() - const messaging = admin.messaging() - const sessionRef = db.collection('couples').doc(coupleId).collection('sessions').doc(sessionId) + const db = admin.firestore() + const messaging = admin.messaging() + const sessionRef = db.collection('couples').doc(coupleId).collection('sessions').doc(sessionId) - // Claim a one-time flag on the SESSION doc (consistent with start/finishNotifiedAt; rule-safe; - // writing it re-fires onGameSessionUpdate but that no-ops on an active+already-started session). - const claimed = await db.runTransaction(async (tx) => { - const fresh = await tx.get(sessionRef) - const d = fresh.data() - if (!fresh.exists || !d) return false - if (d.status === 'completed' || d.partFinishNotifiedAt) return false - tx.update(sessionRef, { partFinishNotifiedAt: admin.firestore.FieldValue.serverTimestamp() }) - return true - }) - if (!claimed) return + // Claim a one-time flag on the SESSION doc (consistent with start/finishNotifiedAt; rule-safe; + // writing it re-fires onGameSessionUpdate but that no-ops on an active+already-started session). + const claimed = await db.runTransaction(async (tx) => { + const fresh = await tx.get(sessionRef) + const d = fresh.data() + if (!fresh.exists || !d) return false + if (d.status === 'completed' || d.partFinishNotifiedAt) return false + tx.update(sessionRef, { partFinishNotifiedAt: admin.firestore.FieldValue.serverTimestamp() }) + return true + }) + if (!claimed) return - const coupleDoc = await db.collection('couples').doc(coupleId).get() - const userIds = (coupleDoc.data()?.userIds ?? []) as string[] - const recipient = userIds.find((u) => u !== finisherUid) - if (!recipient) return - const finisher = await db.collection('users').doc(finisherUid).get() - const finisherName = 'Your partner' // displayName is E2EE; the app shows the real name in-app - const finisherAvatar = finisher.data()?.photoUrl as string | undefined + const coupleDoc = await db.collection('couples').doc(coupleId).get() + const userIds = (coupleDoc.data()?.userIds ?? []) as string[] + const recipient = userIds.find((u) => u !== finisherUid) + if (!recipient) return + const finisher = await db.collection('users').doc(finisherUid).get() + const finisherName = 'Your partner' // displayName is E2EE; the app shows the real name in-app + const finisherAvatar = finisher.data()?.photoUrl as string | undefined - await notifyPartner( - db, messaging, recipient, finisherName, gameType, - 'partner_completed_part', yourTurnBody(gameType), coupleId, - finisherAvatar, sessionId - ) - } + await notifyPartner( + db, messaging, recipient, finisherName, gameType, + 'partner_completed_part', yourTurnBody(gameType), coupleId, + finisherAvatar, sessionId + ) +} + +export const onThisOrThatPartFinished = onDocumentWritten( + 'couples/{coupleId}/this_or_that/{sessionId}', + (event) => handleGamePartFinished(event.params.coupleId, 'this_or_that', event.params.sessionId, event.data) +) +export const onWheelPartFinished = onDocumentWritten( + 'couples/{coupleId}/wheel/{sessionId}', + (event) => handleGamePartFinished(event.params.coupleId, 'wheel', event.params.sessionId, event.data) +) +export const onHowWellPartFinished = onDocumentWritten( + 'couples/{coupleId}/how_well/{sessionId}', + (event) => handleGamePartFinished(event.params.coupleId, 'how_well', event.params.sessionId, event.data) +) +export const onDesireSyncPartFinished = onDocumentWritten( + 'couples/{coupleId}/desire_sync/{sessionId}', + (event) => handleGamePartFinished(event.params.coupleId, 'desire_sync', event.params.sessionId, event.data) ) /** diff --git a/functions/src/index.ts b/functions/src/index.ts index ea0d36df..a5a40244 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -43,7 +43,13 @@ export { submitOutcomeCallable } from './couples/submitOutcomeCallable' export { aggregateOutcomeStats } from './couples/aggregateOutcomes' export { scheduledOutcomesReminder } from './couples/scheduledOutcomesReminder' export { onUserDelete } from './users/onUserDelete' -export { onGameSessionUpdate, onGamePartFinished } from './games/onGameSessionUpdate' +export { + onGameSessionUpdate, + onThisOrThatPartFinished, + onWheelPartFinished, + onHowWellPartFinished, + onDesireSyncPartFinished, +} from './games/onGameSessionUpdate' export { wrapReleaseKeyCallable } from './releaseKey/wrapReleaseKeyCallable'