From fce2e7caf18bfb39fa07b552542023e223e80203 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 25 Aug 2026 22:56:58 +0000 Subject: [PATCH 1/2] Document Android push-notification troubleshooting for Mattermost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Covers the migrated-from-PikaPods case: stale device registrations carried over by the DB import, server-to-push-proxy connectivity, OEM battery optimization, and the push-content setting — the likely causes when only some Android users stop getting background pushes. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01AddPmva5bfrUW3MoPriq21 --- services/mattermost.md | 81 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 services/mattermost.md diff --git a/services/mattermost.md b/services/mattermost.md new file mode 100644 index 0000000..93fcccc --- /dev/null +++ b/services/mattermost.md @@ -0,0 +1,81 @@ +## Android push notifications inconsistent after a migration (e.g. from PikaPods) + +Symptom: "Enable Push Notifications" is on in System Console, but only some +Android users actually get background push notifications — one user gets +them reliably, others on the same server don't. Since this is per-device +rather than server-wide, work through these in order; the first that +reproduces the symptom is almost always the actual cause. + +### 1. Rule out server → push-proxy connectivity first (quick, and if this is +broken it explains ALL users failing, not just some) + +The mobile app talks to Google's FCM directly for the device token, but it's +*your* Mattermost server that calls out to the push relay (default +`https://push.mattermost.com`, System Console → Environment → Push +Notification Server) every time it needs to fan out a push. Confirm the new +VPS can actually reach it — a fresh box's outbound rules, or a NAT/firewall +inherited from the migration, can block this silently: + +```bash +docker exec mattermost curl -Is https://push.mattermost.com | head -1 +``` + +Then check the server's own logs for push attempts/failures: + +```bash +docker compose logs mattermost | grep -i push +``` + +If specific users' pushes error out while others succeed, that already rules +out a global connectivity/config problem and points at something per-account +(section 2) or per-device (section 3). + +### 2. Stale device registration carried over by the migration + +A SQL dump import (`migrate-from-pikapods.sh` or any other DB restore) brings +the `Sessions` table with it — including each user's `DeviceId`, the +FCM token that was registered against the *old* server. That registration +only gets refreshed on a real login, not by the app quietly staying open: +a session that survived the move keeps working perfectly for live chat +(the websocket connection has nothing to do with push registration) while +its background push silently stops working, because the token behind it may +now be stale. + +This matches "one user is always fine, everyone else isn't" almost exactly — +the working user is typically the one who happened to log out/in (or +reinstalled the app) since the migration, refreshing their `DeviceId`, while +everyone else's session rode through the import unchanged. + +**Fix:** have affected users fully log out of the Mattermost Android app +(not just background it — Menu → Log Out) and log back in. This forces a +fresh device-token registration against the current server. + +### 3. Android OEM battery optimization (the most common purely-device-side cause) + +Xiaomi/MIUI, Huawei, Samsung, OnePlus, and Oppo/Vivo all ship aggressive +battery managers that kill background apps and their FCM listeners by +default — independent of anything about the server. This is the single most +common reason some Android phones on the exact same server get pushes and +others don't, migration or no migration. Have affected users check, per +device: + +- **Settings → Apps → Mattermost → Battery** → set to "Unrestricted" / "No + restrictions" / disable "Battery Saver" for the app (menu wording varies + by OEM/Android version). +- **Notification permission itself** is still granted — Android 13+ requires + an explicit runtime permission that can get silently revoked (e.g. after + an OS update), separate from the app's own in-app notification settings. +- Some OEMs (Xiaomi especially) also gate this behind a separate + "Autostart" toggle for the app. + +### 4. Push notification content setting, if section 1 and 2 don't explain it + +System Console → Environment → Push Notification Server → **Push +Notification Contents**. If set to anything other than "Send full message +contents", the client has to phone the server's own `SiteURL` back for the +real content after getting the push shell — so if the *new* domain isn't +reliably reachable from a given user's network (split-horizon DNS, a mobile +carrier blocking something, a half-finished Caddy/DNS cutover for the new +VPS), that user can receive the push notification itself but never see +real content, or see it inconsistently. Temporarily switching to "Send full +message contents" removes this variable while narrowing down the cause. From 31ba6678d7e68688d9e99b5fa75fbda398d6f1a4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 26 Aug 2026 00:08:18 +0000 Subject: [PATCH 2/2] Add FQDN-change-specific causes to the push-notification troubleshooting doc DNS propagation lag, TLS cert readiness, and a stale SiteURL all follow directly from a migration that also changes domains, on top of the DB-import device-registration cause already documented. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01AddPmva5bfrUW3MoPriq21 --- services/mattermost.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/services/mattermost.md b/services/mattermost.md index 93fcccc..6c7cd62 100644 --- a/services/mattermost.md +++ b/services/mattermost.md @@ -79,3 +79,30 @@ carrier blocking something, a half-finished Caddy/DNS cutover for the new VPS), that user can receive the push notification itself but never see real content, or see it inconsistently. Temporarily switching to "Send full message contents" removes this variable while narrowing down the cause. + +### 5. A changed FQDN specifically — DNS propagation and cert readiness + +If the migration also moved the server to a new domain (not just a new box +under the same domain), that alone can produce exactly this +some-users-fine/some-users-not pattern for a few days after cutover, on top +of section 2 and 4 above: + +- **DNS propagation lags per device.** Different users' resolvers (ISP DNS, + carrier DNS on cellular, cached records with old TTLs) pick up the new + FQDN's IP at different times. A user on a fast public resolver sees it + immediately; someone on carrier DNS with a stale cache might not resolve + it correctly for hours. Combined with section 4 (anything but "full + message contents" requires a content-fetch call back to `SiteURL`), a + device with a stale answer for the new FQDN fails that step while others + succeed. +- **TLS certificate not fully issued/propagated yet** for the new FQDN + (Caddy/Let's Encrypt) causes the same content-fetch failure via cert + validation instead of DNS. +- **Confirm `MM_SERVICESETTINGS_SITEURL` in `.env` is actually the new FQDN** + — a value left over from before the domain change points every client's + content-fetch at the wrong place, consistently, not just intermittently. +- Users who never explicitly added the new server URL in the mobile app (a + kept redirect from the old domain let them keep working without + noticing) are still running on their old, stale device registration — + this is section 2's mechanism, just caused directly by the FQDN change + rather than by the DB import alone.