fix(notif): deep-link results-ready pushes to per-session results/replay screen (E-003)
This commit is contained in:
parent
3de4178fd3
commit
aaab768cb0
|
|
@ -274,11 +274,10 @@ enum class PartnerNotificationType(
|
|||
PARTNER_STARTED_GAME -> gameRouteForType(payload.gameType) ?: AppRoute.PLAY
|
||||
PARTNER_COMPLETED_PART -> gameRouteForType(payload.gameType) ?: AppRoute.PLAY
|
||||
// Results-ready means the session is COMPLETED, so the plain game route would show "start a
|
||||
// new game" (getActiveSession returns only active sessions). The correct target is the
|
||||
// per-session results/replay route — but that needs the server to also send game_session_id
|
||||
// in the FCM data (currently it sends only game_type). Until that server change ships, route
|
||||
// to the Play hub rather than a misleading setup screen. E-003 (results-ready follow-up).
|
||||
GAME_RESULTS_READY -> AppRoute.PLAY
|
||||
// new game" (getActiveSession returns only active sessions). Deep link to the per-session
|
||||
// results/replay route instead, using game_session_id + game_type from the FCM data. Falls
|
||||
// back to the hub only if the server didn't send the session id. E-003 (results-ready).
|
||||
GAME_RESULTS_READY -> gameResultsRouteFor(payload.gameType, payload.gameSessionId) ?: AppRoute.PLAY
|
||||
CHALLENGE_WAITING -> AppRoute.CONNECTION_CHALLENGES
|
||||
CAPSULE_UNLOCKED -> AppRoute.MEMORY_LANE
|
||||
GENTLE_REMINDER -> AppRoute.DAILY_QUESTION
|
||||
|
|
@ -355,3 +354,18 @@ private fun gameRouteForType(gameType: String?): String? = when (gameType) {
|
|||
GameType.DESIRE_SYNC -> AppRoute.DESIRE_SYNC
|
||||
else -> null
|
||||
}
|
||||
|
||||
/**
|
||||
* The per-session results/replay route for a COMPLETED game, so a "results ready" push opens the
|
||||
* actual results (not the game's setup screen). Needs both the game type and the session id. E-003.
|
||||
*/
|
||||
private fun gameResultsRouteFor(gameType: String?, sessionId: String?): String? {
|
||||
if (sessionId.isNullOrBlank()) return null
|
||||
return when (gameType) {
|
||||
GameType.WHEEL -> AppRoute.wheelComplete(sessionId)
|
||||
GameType.THIS_OR_THAT -> AppRoute.thisOrThatReplay(sessionId)
|
||||
GameType.HOW_WELL -> AppRoute.howWellReplay(sessionId)
|
||||
GameType.DESIRE_SYNC -> AppRoute.desireSyncReplay(sessionId)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ async function notifyPartnerJoined(
|
|||
title: 'Your partner joined!',
|
||||
body: "You're connected. Time to answer tonight's question together.",
|
||||
},
|
||||
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||
data: {
|
||||
type: 'partner_joined',
|
||||
couple_id: coupleId,
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ export const onCoupleLeave = functions.firestore
|
|||
title: notificationPayload.title,
|
||||
body: notificationPayload.body,
|
||||
},
|
||||
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||
data: {
|
||||
type: notificationPayload.type,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ async function notifyDateMatch(
|
|||
title: "It's a match!",
|
||||
body: "You both want to go on this date. Time to make it happen.",
|
||||
},
|
||||
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||
data: {
|
||||
type: 'date_match',
|
||||
couple_id: coupleId,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export const onGameSessionUpdate = functions.firestore
|
|||
await notifyPartner(
|
||||
db, messaging, recipientId, starterName, gameType,
|
||||
'partner_started_game', `${starterName} has started a game. Tap to join!`, coupleId,
|
||||
starterAvatar
|
||||
starterAvatar, sessionId
|
||||
)
|
||||
return
|
||||
}
|
||||
|
|
@ -81,12 +81,12 @@ export const onGameSessionUpdate = functions.firestore
|
|||
await notifyPartner(
|
||||
db, messaging, partnerA, partnerBName, gt,
|
||||
'partner_finished_game', `${partnerBName} finished — tap to see your results!`, coupleId,
|
||||
avatarB
|
||||
avatarB, sessionId
|
||||
)
|
||||
await notifyPartner(
|
||||
db, messaging, partnerB, partnerAName, gt,
|
||||
'partner_finished_game', `${partnerAName} finished — tap to see your results!`, coupleId,
|
||||
avatarA
|
||||
avatarA, sessionId
|
||||
)
|
||||
return
|
||||
}
|
||||
|
|
@ -104,7 +104,8 @@ async function notifyPartner(
|
|||
notificationType: string,
|
||||
body: string,
|
||||
coupleId: string,
|
||||
senderAvatarUrl?: string
|
||||
senderAvatarUrl?: string,
|
||||
sessionId?: string
|
||||
): Promise<void> {
|
||||
const title =
|
||||
notificationType === 'partner_finished_game'
|
||||
|
|
@ -161,10 +162,16 @@ async function notifyPartner(
|
|||
title: notificationPayload.title,
|
||||
body: notificationPayload.body,
|
||||
},
|
||||
// Put backgrounded notifications on the Games channel instead of the FCM fallback channel,
|
||||
// so importance/sound and the per-category toggle apply. E-OBS.
|
||||
android: { notification: { channelId: 'game_activity' } },
|
||||
data: {
|
||||
type: notificationPayload.type,
|
||||
couple_id: coupleId,
|
||||
game_type: gameType,
|
||||
// Lets the client deep link a results-ready push to the per-session results/replay screen
|
||||
// (a completed session isn't returned by getActiveSession). E-003 results-ready.
|
||||
...(sessionId ? { game_session_id: sessionId } : {}),
|
||||
...(senderAvatarUrl && senderAvatarUrl.length > 0
|
||||
? { sender_avatar_url: senderAvatarUrl }
|
||||
: {}),
|
||||
|
|
|
|||
|
|
@ -191,6 +191,12 @@ async function sendNotification(
|
|||
title: notification.title,
|
||||
body: notification.body,
|
||||
},
|
||||
// E-OBS: challenge reminders → Reminders channel; capsule-unlocked → partner-activity channel.
|
||||
android: {
|
||||
notification: {
|
||||
channelId: notification.type === 'challenge_day_ready' ? 'reminders' : 'partner_activity',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
type: notification.type,
|
||||
...notification.data,
|
||||
|
|
|
|||
|
|
@ -103,7 +103,11 @@ export const onAnswerWritten = functions.firestore
|
|||
|
||||
const sendResults = await Promise.allSettled(
|
||||
tokens.map((token) =>
|
||||
admin.messaging().send({ ...payload, token } as admin.messaging.Message)
|
||||
admin.messaging().send({
|
||||
...payload,
|
||||
token,
|
||||
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||
} as admin.messaging.Message)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,12 @@ export const onMessageWritten = functions.firestore
|
|||
|
||||
const sendResults = await Promise.allSettled(
|
||||
tokens.map((token) =>
|
||||
admin.messaging().send({ ...payload, token } as admin.messaging.Message)
|
||||
admin.messaging().send({
|
||||
...payload,
|
||||
token,
|
||||
// E-OBS: backgrounded delivery on the Chat/partner channel, not the FCM fallback channel.
|
||||
android: { notification: { channelId: 'partner_activity' } },
|
||||
} as admin.messaging.Message)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ async function notifyPartner(
|
|||
title: 'Your partner deleted their account',
|
||||
body: 'You are no longer paired. Tap to create a new invite.',
|
||||
},
|
||||
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||
data: { type: 'partner_deleted_account' },
|
||||
})
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue