Merge pull request #395 from outis1one/claude/mattermost-android-notifications-d02w94
Claude/mattermost android notifications d02w94
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
## 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.
|
||||
|
||||
### 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.
|
||||
Reference in New Issue
Block a user