v0.11.26 FCM bugs fixes

This commit is contained in:
2026-03-22 21:39:09 -04:00
parent ef3935560d
commit d2ed487079
5 changed files with 23 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "rosterchirp-backend", "name": "rosterchirp-backend",
"version": "0.11.25", "version": "0.11.26",
"description": "TeamChat backend server", "description": "TeamChat backend server",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {

View File

@@ -233,17 +233,22 @@ io.on('connection', async (socket) => {
for (const m of members) { for (const m of members) {
if (m.user_id === userId) continue; if (m.user_id === userId) continue;
const memberKey = `${schema}:${m.user_id}`; const memberKey = `${schema}:${m.user_id}`;
if (!onlineUsers.has(memberKey)) { if (onlineUsers.has(memberKey)) {
sendPushToUser(schema, m.user_id, { // In-app notification for connected sockets
title: senderName,
body: (content || (imageUrl ? '📷 Image' : '')).slice(0, 100),
url: '/', groupId, badge: 1,
}).catch(() => {});
} else {
for (const sid of onlineUsers.get(memberKey)) { for (const sid of onlineUsers.get(memberKey)) {
io.to(sid).emit('notification:new', { type: 'private_message', groupId, fromUser: socket.user }); io.to(sid).emit('notification:new', { type: 'private_message', groupId, fromUser: socket.user });
} }
} }
// Always send push — when the app is in the foreground FCM delivers
// silently (no system notification); when backgrounded or offline the
// service worker shows the system notification. This covers the common
// Android case where the socket appears online but is silently dead
// 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),
url: '/', groupId, badge: 1,
}).catch(() => {});
} }
} }

View File

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

View File

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

View File

@@ -47,12 +47,15 @@ export function SocketProvider({ children }) {
window.dispatchEvent(new CustomEvent('rosterchirp:session-displaced')); window.dispatchEvent(new CustomEvent('rosterchirp:session-displaced'));
}); });
// Bug B fix: when app returns to foreground, force socket reconnect if disconnected // When app returns to foreground, force a full disconnect+reconnect.
// The underlying WebSocket is often silently dead after Android background
// suspension while socket.io-client still reports connected (stale state
// until the ping/pong timeout fires ~45s later). Always force a fresh
// connection so the "offline" indicator clears immediately on focus.
const handleVisibilityChange = () => { const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') { if (document.visibilityState === 'visible' && socketRef.current) {
if (socketRef.current && !socketRef.current.connected) { socketRef.current.disconnect();
socketRef.current.connect(); socketRef.current.connect();
}
} }
}; };
document.addEventListener('visibilitychange', handleVisibilityChange); document.addEventListener('visibilitychange', handleVisibilityChange);