diff --git a/server/public/home.html b/server/public/home.html index 3c64ee8..5a85bb8 100644 --- a/server/public/home.html +++ b/server/public/home.html @@ -3710,22 +3710,28 @@ function reportInstall(){ }catch(_){} } let _nativeTok=null; +// TEMP push diagnostics: mirror each step to the server so we can see where iOS registration fails +// without a Mac/device console. Remove once native push is confirmed working end-to-end. +function pdbg(step, extra){ try{ postJSON('/api/v1/push-debug', Object.assign({ step, t: Date.now() }, extra||{})).catch(()=>{}); }catch(_){} + try{ console.log('[push]', step, extra||''); }catch(_){} } async function setupNativePush(){ const PN=capPlugin('PushNotifications'); const plat=nativePlatform(); - if(!PN || (plat!=='ios' && plat!=='android')) return false; // not a mobile native app + const C=window.Capacitor; + pdbg('native-setup-enter', { plat, hasPlugin: !!PN, isNative: !!(C&&C.isNativePlatform&&C.isNativePlatform()), plugins: (C&&C.Plugins)?Object.keys(C.Plugins).join(','):'' }); + if(!PN || (plat!=='ios' && plat!=='android')){ pdbg('native-setup-skip', { plat, hasPlugin: !!PN }); return false; } // not a mobile native app try{ - PN.addListener('registration', async (t)=>{ const token=t&&t.value; if(!token) return; _nativeTok=token; - try{ await postJSON('/api/v1/devices',{ platform:plat, token }); pushActive=true; console.log('[push] native device registered'); } - catch(e){ console.warn('[push] device register failed:', e); } }); - PN.addListener('registrationError', (e)=>console.warn('[push] native registration error:', e)); + PN.addListener('registration', async (t)=>{ const token=t&&t.value; pdbg('registration-event', { tokenLen: token?token.length:0 }); if(!token) return; _nativeTok=token; + try{ await postJSON('/api/v1/devices',{ platform:plat, token }); pushActive=true; pdbg('device-post-ok', { plat }); console.log('[push] native device registered'); } + catch(e){ pdbg('device-post-fail', { err:String((e&&e.message)||e) }); console.warn('[push] device register failed:', e); } }); + PN.addListener('registrationError', (e)=>{ pdbg('registration-error', { err:(e&&(e.error||e.message))||JSON.stringify(e) }); console.warn('[push] native registration error:', e); }); // Tapping an OS notification opens the relevant chat (payload carries kind+id). PN.addListener('pushNotificationActionPerformed', (a)=>{ try{ const d=(a&&a.notification&&a.notification.data)||{}; if(d.id) selectChat(d.kind||'dm', d.id); }catch(_){} }); - let perm=await PN.checkPermissions(); - if(perm.receive!=='granted') perm=await PN.requestPermissions(); - if(perm.receive!=='granted'){ console.log('[push] native permission not granted'); return true; } - await PN.register(); + let perm=await PN.checkPermissions(); pdbg('perm-check', { receive: perm&&perm.receive }); + if(perm.receive!=='granted'){ perm=await PN.requestPermissions(); pdbg('perm-after-request', { receive: perm&&perm.receive }); } + if(perm.receive!=='granted'){ pdbg('perm-not-granted', { receive: perm&&perm.receive }); console.log('[push] native permission not granted'); return true; } + await PN.register(); pdbg('register-called'); console.log('[push] native push registered'); - }catch(e){ console.warn('[push] native push setup failed:', e); } + }catch(e){ pdbg('native-setup-exception', { err:String((e&&e.message)||e) }); console.warn('[push] native push setup failed:', e); } return true; // handled the native path (skip Web Push regardless of outcome) } async function setupPush(){ diff --git a/server/routes.js b/server/routes.js index 17037e0..510dbee 100644 --- a/server/routes.js +++ b/server/routes.js @@ -424,6 +424,18 @@ route('POST', '/api/devices/remove', async (req, res) => { json(res, 200, { ok: true }); }); +// --- Push diagnostics (temporary): the native app reports each step of push setup here so we can see +// WHERE iOS registration fails without a Mac/device console. Best-effort; logs and returns 200. --- +route('POST', '/api/push-debug', async (req, res) => { + try { + const b = await readBody(req); + let uid = 'anon'; try { const u = await currentUser(req); if (u) uid = u.id; } catch (_) {} + const line = (typeof b === 'object' ? JSON.stringify(b) : String(b)).slice(0, 800); + console.log('[push-debug] user=' + uid + ' ' + line); + } catch (_) {} + json(res, 200, { ok: true }); +}); + // --- App install telemetry: records each install and, once the user signs in, who's using it. --- route('POST', '/api/telemetry/install', async (req, res) => { const { installId, platform, appVersion, os } = await readBody(req);