Mobile API Best Practices · Offline-First & Sync
Background Sync, Push & Silent Notifications
Keeping data fresh when the app isn't open.
Mobile OSes limit background work. To keep data fresh: send push notifications (APNs/FCM) for user-visible events, silent/data pushes to hint "something changed — sync" (throttled and not guaranteed), and schedule periodic background tasks (WorkManager, BGTaskScheduler) the OS runs opportunistically. Always do a sync on app foreground. Push payloads should be small hints, not data, and never contain secrets.
Freshness mechanisms
| Mechanism | Delivery | Use for | Limits |
|---|---|---|---|
| Visible push (APNs/FCM) | Best effort, usually seconds | Messages, alerts | User permission required |
| Silent / data push | Throttled, may be dropped | 'Sync now' hints | OS budgets; app killed by user → none (iOS) |
| Periodic background task | OS-scheduled | Prefetch, cleanup | Minimum intervals; not exact |
| Foreground sync | When opened | Guaranteed freshness | Only while in use |
| Persistent socket | Real-time | Active chat/calls | Foreground only (except VoIP/special) |
POST https://fcm.googleapis.com/v1/projects/my-app/messages:send
{
"message": {
"token": "<device registration token>",
"data": {"kind": "sync", "scope": "tasks", "hint_seq": "124487"},
"android": {"priority": "normal", "collapse_key": "sync-tasks"},
"apns": {"headers": {"apns-push-type": "background", "apns-priority": "5"},
"payload": {"aps": {"content-available": 1}}}
}
}
async def send_push(device: Device, message: dict) -> None:
try:
await fcm.send(device.token, message)
except UnregisteredTokenError:
await devices.delete(device.id) # app uninstalled or token rotated
except QuotaExceededError:
await requeue_with_backoff(device, message)
Common pitfalls
- Relying on silent push for correctness.
- Sensitive data in push payloads (shown on lock screens, stored by providers).
- Never pruning dead device tokens.
Key points
- Push = hint, sync = truth
- Sync on foreground
- Prune invalid tokens
Further reading: Firebase Cloud Messaging: message types
Practice questions
Why shouldn't you rely on silent pushes to keep data correct?
Answer
OSes throttle or drop them (battery budgets, force-quit apps), so they're only hints; correctness comes from sync on launch/foreground and periodic sync.
What should a server do when FCM/APNs reports a token as unregistered?
Answer
Delete or deactivate that device token so you stop sending to it and keep delivery metrics meaningful.
Open in the app to mark lessons complete, take notes and track your progress.