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_STARTED_GAME -> gameRouteForType(payload.gameType) ?: AppRoute.PLAY
|
||||||
PARTNER_COMPLETED_PART -> 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
|
// 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
|
// new game" (getActiveSession returns only active sessions). Deep link to the per-session
|
||||||
// per-session results/replay route — but that needs the server to also send game_session_id
|
// results/replay route instead, using game_session_id + game_type from the FCM data. Falls
|
||||||
// in the FCM data (currently it sends only game_type). Until that server change ships, route
|
// back to the hub only if the server didn't send the session id. E-003 (results-ready).
|
||||||
// to the Play hub rather than a misleading setup screen. E-003 (results-ready follow-up).
|
GAME_RESULTS_READY -> gameResultsRouteFor(payload.gameType, payload.gameSessionId) ?: AppRoute.PLAY
|
||||||
GAME_RESULTS_READY -> AppRoute.PLAY
|
|
||||||
CHALLENGE_WAITING -> AppRoute.CONNECTION_CHALLENGES
|
CHALLENGE_WAITING -> AppRoute.CONNECTION_CHALLENGES
|
||||||
CAPSULE_UNLOCKED -> AppRoute.MEMORY_LANE
|
CAPSULE_UNLOCKED -> AppRoute.MEMORY_LANE
|
||||||
GENTLE_REMINDER -> AppRoute.DAILY_QUESTION
|
GENTLE_REMINDER -> AppRoute.DAILY_QUESTION
|
||||||
|
|
@ -355,3 +354,18 @@ private fun gameRouteForType(gameType: String?): String? = when (gameType) {
|
||||||
GameType.DESIRE_SYNC -> AppRoute.DESIRE_SYNC
|
GameType.DESIRE_SYNC -> AppRoute.DESIRE_SYNC
|
||||||
else -> null
|
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!',
|
title: 'Your partner joined!',
|
||||||
body: "You're connected. Time to answer tonight's question together.",
|
body: "You're connected. Time to answer tonight's question together.",
|
||||||
},
|
},
|
||||||
|
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||||
data: {
|
data: {
|
||||||
type: 'partner_joined',
|
type: 'partner_joined',
|
||||||
couple_id: coupleId,
|
couple_id: coupleId,
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ export const onCoupleLeave = functions.firestore
|
||||||
title: notificationPayload.title,
|
title: notificationPayload.title,
|
||||||
body: notificationPayload.body,
|
body: notificationPayload.body,
|
||||||
},
|
},
|
||||||
|
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||||
data: {
|
data: {
|
||||||
type: notificationPayload.type,
|
type: notificationPayload.type,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ async function notifyDateMatch(
|
||||||
title: "It's a match!",
|
title: "It's a match!",
|
||||||
body: "You both want to go on this date. Time to make it happen.",
|
body: "You both want to go on this date. Time to make it happen.",
|
||||||
},
|
},
|
||||||
|
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||||
data: {
|
data: {
|
||||||
type: 'date_match',
|
type: 'date_match',
|
||||||
couple_id: coupleId,
|
couple_id: coupleId,
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ export const onGameSessionUpdate = functions.firestore
|
||||||
await notifyPartner(
|
await notifyPartner(
|
||||||
db, messaging, recipientId, starterName, gameType,
|
db, messaging, recipientId, starterName, gameType,
|
||||||
'partner_started_game', `${starterName} has started a game. Tap to join!`, coupleId,
|
'partner_started_game', `${starterName} has started a game. Tap to join!`, coupleId,
|
||||||
starterAvatar
|
starterAvatar, sessionId
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -81,12 +81,12 @@ export const onGameSessionUpdate = functions.firestore
|
||||||
await notifyPartner(
|
await notifyPartner(
|
||||||
db, messaging, partnerA, partnerBName, gt,
|
db, messaging, partnerA, partnerBName, gt,
|
||||||
'partner_finished_game', `${partnerBName} finished — tap to see your results!`, coupleId,
|
'partner_finished_game', `${partnerBName} finished — tap to see your results!`, coupleId,
|
||||||
avatarB
|
avatarB, sessionId
|
||||||
)
|
)
|
||||||
await notifyPartner(
|
await notifyPartner(
|
||||||
db, messaging, partnerB, partnerAName, gt,
|
db, messaging, partnerB, partnerAName, gt,
|
||||||
'partner_finished_game', `${partnerAName} finished — tap to see your results!`, coupleId,
|
'partner_finished_game', `${partnerAName} finished — tap to see your results!`, coupleId,
|
||||||
avatarA
|
avatarA, sessionId
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -104,7 +104,8 @@ async function notifyPartner(
|
||||||
notificationType: string,
|
notificationType: string,
|
||||||
body: string,
|
body: string,
|
||||||
coupleId: string,
|
coupleId: string,
|
||||||
senderAvatarUrl?: string
|
senderAvatarUrl?: string,
|
||||||
|
sessionId?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const title =
|
const title =
|
||||||
notificationType === 'partner_finished_game'
|
notificationType === 'partner_finished_game'
|
||||||
|
|
@ -161,10 +162,16 @@ async function notifyPartner(
|
||||||
title: notificationPayload.title,
|
title: notificationPayload.title,
|
||||||
body: notificationPayload.body,
|
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: {
|
data: {
|
||||||
type: notificationPayload.type,
|
type: notificationPayload.type,
|
||||||
couple_id: coupleId,
|
couple_id: coupleId,
|
||||||
game_type: gameType,
|
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
|
...(senderAvatarUrl && senderAvatarUrl.length > 0
|
||||||
? { sender_avatar_url: senderAvatarUrl }
|
? { sender_avatar_url: senderAvatarUrl }
|
||||||
: {}),
|
: {}),
|
||||||
|
|
|
||||||
|
|
@ -191,6 +191,12 @@ async function sendNotification(
|
||||||
title: notification.title,
|
title: notification.title,
|
||||||
body: notification.body,
|
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: {
|
data: {
|
||||||
type: notification.type,
|
type: notification.type,
|
||||||
...notification.data,
|
...notification.data,
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,11 @@ export const onAnswerWritten = functions.firestore
|
||||||
|
|
||||||
const sendResults = await Promise.allSettled(
|
const sendResults = await Promise.allSettled(
|
||||||
tokens.map((token) =>
|
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(
|
const sendResults = await Promise.allSettled(
|
||||||
tokens.map((token) =>
|
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',
|
title: 'Your partner deleted their account',
|
||||||
body: 'You are no longer paired. Tap to create a new invite.',
|
body: 'You are no longer paired. Tap to create a new invite.',
|
||||||
},
|
},
|
||||||
|
android: { notification: { channelId: 'partner_activity' } }, // E-OBS
|
||||||
data: { type: 'partner_deleted_account' },
|
data: { type: 'partner_deleted_account' },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue