v0.12.26 FCM feature changes

This commit is contained in:
2026-03-24 19:04:09 -04:00
parent 225dcd718b
commit f48ce589ca
5 changed files with 27 additions and 6 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "rosterchirp-backend",
"version": "0.12.25",
"version": "0.12.26",
"description": "RosterChirp backend server",
"main": "src/index.js",
"scripts": {

View File

@@ -224,12 +224,14 @@ io.on('connection', async (socket) => {
message.reactions = [];
io.to(R('group', groupId)).emit('message:new', message);
// Push notifications for private groups
// Push notifications
const senderName = socket.user.display_name || socket.user.name || 'Someone';
const msgBody = (content || (imageUrl ? '📷 Image' : '')).slice(0, 100);
if (group.type === 'private') {
const members = await query(schema,
'SELECT user_id FROM group_members WHERE group_id = $1', [groupId]
);
const senderName = socket.user.display_name || socket.user.name || 'Someone';
for (const m of members) {
if (m.user_id === userId) continue;
const memberKey = `${schema}:${m.user_id}`;
@@ -246,7 +248,21 @@ io.on('connection', async (socket) => {
// after the PWA was backgrounded (OS kills WebSocket before ping timeout).
sendPushToUser(schema, m.user_id, {
title: senderName,
body: (content || (imageUrl ? '📷 Image' : '')).slice(0, 100),
body: msgBody,
url: '/', groupId, badge: 1,
}).catch(() => {});
}
} else if (group.type === 'public') {
// Push to all users who have registered an FCM token — everyone is implicitly
// a member of every public group. Skip the sender.
const subUsers = await query(schema,
'SELECT DISTINCT user_id FROM push_subscriptions WHERE fcm_token IS NOT NULL AND user_id != $1',
[userId]
);
for (const sub of subUsers) {
sendPushToUser(schema, sub.user_id, {
title: `${senderName} in ${group.name}`,
body: msgBody,
url: '/', groupId, badge: 1,
}).catch(() => {});
}

View File

@@ -36,6 +36,10 @@ async function sendPushToUser(schema, userId, payload) {
'SELECT * FROM push_subscriptions WHERE user_id = $1 AND fcm_token IS NOT NULL',
[userId]
);
if (subs.length === 0) {
console.log(`[Push] No FCM token for user ${userId} (schema=${schema})`);
return;
}
for (const sub of subs) {
try {
await messaging.send({
@@ -70,6 +74,7 @@ async function sendPushToUser(schema, userId, payload) {
fcm_options: { link: payload.url || '/' },
},
});
console.log(`[Push] Sent to user ${userId} device=${sub.device} schema=${schema}`);
} catch (err) {
// Remove stale tokens
const stale = [

View File

@@ -13,7 +13,7 @@
# ─────────────────────────────────────────────────────────────
set -euo pipefail
VERSION="${1:-0.12.25}"
VERSION="${1:-0.12.26}"
ACTION="${2:-}"
REGISTRY="${REGISTRY:-}"
IMAGE_NAME="rosterchirp"

View File

@@ -1,6 +1,6 @@
{
"name": "rosterchirp-frontend",
"version": "0.12.25",
"version": "0.12.26",
"private": true,
"scripts": {
"dev": "vite",