| 1 |
App recently used → calls work, after 15–30 min no incoming call |
Android + iOS |
App gets suspended/killed by OS, background isolate dead |
Ensure server sends high_priority data-only FCM. Confirm onBackgroundMessage registered. |
Android: Foreground Service + keep-alive socket. iOS: PushKit VoIP pushes. Hybrid: socket + fallback to push. |
High |
Use FCM as fallback when socket disconnected. |
| 2 |
Incoming call not showing when screen locked |
Android |
No overlay permission / background isolate not showing UI |
Ask user to enable "Display over other apps" & allow notifications |
Use CallKit (iOS) / proper overlay handling with SYSTEM_ALERT_WINDOW on Android; show call via native activity from background. |
High |
Heads-up notification possible if overlay not allowed. |
| 3 |
iOS: No incoming call when app terminated |
iOS |
Using FCM instead of PushKit; APNs VoIP not implemented |
Stop relying on FCM for iOS call wake |
Implement PushKit (VoIP) on server & client; trigger CallKit within PushKit handler. |
Critical |
FCM only works when app not fully terminated. |
| 4 |
Android: App killed by OEM (Xiaomi/Oppo/Realme/Vivo) |
Android |
Aggressive OEM battery optimization / auto-start disabled |
Provide in-app instructions to disable battery optimization & enable auto-start |
Implement Foreground Service and ask users to whitelist app in OEM settings; show onboarding flow to guide enabling. |
Critical |
High-priority FCM may still arrive but not reliable. |
| 5 |
App force-stopped via App Info (user) |
Android |
OS blocks app from receiving broadcasts/FCM until user opens app |
Prompt user to re-open app; show message explaining force-stop blocks calls |
In onboarding, explain not to force-stop. Design UX to prevent accidental force-stop. |
Medium |
Cannot programmatically recover — user action required. |
| 6 |
Background isolates die / onBackgroundMessage not executed |
Android (Flutter) |
Missing handler registration or missing @pragma('vm:entry-point') |
Verify FirebaseMessaging.onBackgroundMessage registration & function marked with @pragma('vm:entry-point') |
Ensure all plugins initialized in background handler and catch errors — keep handler minimal and robust. |
High |
Log background handler errors to Sentry. |
| 7 |
Notifications arrive but CallKit/CallKeep not showing UI |
Android + iOS |
Wrong payload or not calling CallKit library from background thread |
In background handler, call FlutterCallkitIncoming.showCallkitIncoming(...) with proper params |
Make call UI creation synchronous and minimal; ensure native plugin initialized in background isolate. |
High |
If CallKit fails, fallback to normal notification with "Tap to open app" action. |
| 8 |
FCM delayed / batched / throttled |
Android + iOS |
Low priority messages, Doze mode, OEM throttling |
Set priority: "high" and use data-only payload |
Use socket for live users; use exponential retry logic for signaling server; use PushKit for iOS. |
High |
Retry sending push from server; use alternate APNs/FCM endpoints if available. |
| 9 |
Token mismatch or stale device token |
Android + iOS |
Token not updated on server after refresh |
Validate token on login; force token refresh and re-send to server |
Implement token lifecycle: on token refresh, call backend API to update token; handle duplicate tokens per user. |
High |
If token invalid, server should mark it and ask client to re-register. |
| 10 |
Background data disabled / Data saver blocks socket |
Android + iOS |
User settings / OS policy |
Show UI asking user to enable background data for app |
Add reconnect logic; use push fallback when socket unavailable. |
Medium |
Inform user in settings screen. |
| 11 |
Microphone / Call permission denied |
Android + iOS |
User denied mic or call permissions |
Show permission request dialog with rationale |
Graceful degrade: show message explaining need and deep-link to app settings. |
Medium |
Without mic permission caller can still receive call UI (but can't talk). |
| 12 |
Do Not Disturb blocking sounds |
Android |
DND settings blocking notification sound |
Use high importance notifications and request exemption if appropriate |
In-call UI should request audio focus; document DND behavior in FAQ. |
Low |
CallKit typically bypasses DND on iOS; Android varies. |
| 13 |
App standby / long unused app (background) |
Android |
App moved to standby bucket; reduced network access |
Use high-priority FCM; ask user to open app periodically |
Keep socket alive via Foreground Service for online users; encourage regular app opens. |
Medium |
Long-term user inactivity will hurt delivery; use email/SMS fallback for critical alerts. |
| 14 |
VPN / Firewall blocking FCM / socket |
Android + iOS |
Network-level blocking |
Detect failure to connect and show message suggesting disabling VPN |
Implement retry and alternate endpoints / websockets over ws/wss on common ports. |
Low |
Fallback to SMS as last resort (if number available). |
| 15 |
APNs VoIP certificate issues / PushKit rejected |
iOS |
Wrong cert, expired, or payload malformed |
Check push provider logs; verify VoIP certificate & key |
Use token-based APNs auth or maintain cert rotation; validate payload structure. |
Critical |
Monitor APNs responses & log failures. |
| 16 |
Background audio session conflicts (CallKit) |
iOS |
AVAudioSession not configured correctly |
Ensure CallKit callback sets up AVAudioSession on main thread |
Use CallKit template for audio session management (activate/deactivate). |
High |
Misconfigured session can crash or mute audio. |
| 17 |
Wrong callId / duplicate call events |
Android + iOS |
Server sends inconsistent callId or retries create duplicate UI |
Add idempotency: if callId already exists ignore duplicate |
Implement server-side dedupe and client-side idempotency using callId. |
High |
Provide UI to merge duplicate calls or ignore new duplicates. |
| 18 |
Heads-up notifications suppressed (channel settings) |
Android |
Notification channel low importance or disabled |
Ensure call notification channel is IMPORTANCE_HIGH and shows heads-up |
On first open create proper channel; if user changed, deep-link to channel settings. |
Medium |
Android 8+ uses channels — create on install. |
| 19 |
Socket disconnects when app backgrounded |
Android |
Socket closed by OS when app backgrounded |
Use Foreground Service to keep socket alive |
Use resumable connection with heartbeat and exponential backoff; consider using MQTT for persistent connections. |
High |
Always fallback to push if socket down. |
| 20 |
App updated / data cleared → token lost |
Android + iOS |
App data cleared or reinstall changes token |
Force token re-registration on first launch after update |
Persist mapping server-side; require login to re-establish device mapping. |
Medium |
Notify support if many users experience call failures after update. |
| 21 |
User in low-network (2G) |
Android + iOS |
High latency & packet loss |
Show “poor network” banner; retry signaling |
Use low-bitrate codecs and robust retry; fallback to voice-only or scheduled callbacks. |
Medium |
For calls, ask to switch to better network or schedule callback. |
| 22 |
App crashes in background handler |
Android |
Uncaught exception in background isolate |
Add try/catch and error logging in onBackgroundMessage |
Keep background handler minimal, avoid complex logic; send analytic logs for failures. |
High |
Crash prevents future background handling — must fix quickly. |
| 23 |
Foreground service not started / removed by OEM |
Android |
OEM kills service or denies auto-start |
Request user to whitelist app; show clear onboarding steps |
Use persistent notification & restart service on boot and on network reconnect; use platform-specific OEM guides. |
High |
Some OEMs still kill; combine with push fallback. |
| 24 |
User swipes app away (recent tasks) |
Android |
Some OEMs interpret as force-stop |
Provide in-app guidance — cannot programmatically prevent |
Accept limitation; rely on push as best-effort; request user to reopen app periodically. |
Low |
Document behavior in FAQ. |
| 25 |
APNs / FCM throttling from server due to abuse |
Android + iOS |
Too many pushes, server misconfigured |
Reduce duplicate pushes; follow provider quotas |
Implement exponential backoff, bulk send best practices, and monitor provider responses. |
Medium |
Provider may block or delay messages temporarily. |
| 26 |
Wrong payload structure for call UI |
Android + iOS |
Missing required params (callerName, callId, uuid) |
Use a canonical payload & test on device |
Create a server-side schema validation for payloads; include sample JSON in repo. |
High |
Invalid payload causes client to ignore or crash. |
| 27 |
Background permissions (Android 13+) |
Android |
New runtime background start restrictions |
Request POST_NOTIFICATIONS and background start permission flows |
Follow Android docs for background task start; use foreground service for continuous tasks. |
High |
Keep app up-to-date with latest Android changes. |
| 28 |
Time drift / device time incorrect causing signature failures |
Android + iOS |
Token or signature timestamp mismatch |
Validate device time and retry when NTP sync logs errors |
Fail-safe: allow short clock skew on server; log devices with wrong time. |
Low |
Rare but hard to debug. |
| 29 |
Multiple devices for same account receiving calls |
Android + iOS |
Server broadcasting to all device tokens |
Implement device-level signaling: target only active device or show on all with presence |
Add presence tracking: "active device" boolean or socket affinity. |
Medium |
User may want multi-device ringing — make it configurable. |
| 30 |
Background execution time limit reached on iOS |
iOS |
Background task allowed time expired |
Keep PushKit quick and minimal; trigger CallKit instantly |
Use PushKit to wake app and present CallKit within allowed time window. |
High |
Avoid heavy work in PushKit handler. |
Comments
Post a Comment