Implementing Trading Bot Deal Push Notifications
Trading bot closed position overnight — user saw notification in morning. By then price moved 8%, reaction window lost. Push notifications for trading bot — not "nice feature" but part of trader's workflow.
Common Failure Points
Typical problem: bot runs on server, sends notification via FCM, but on Android with battery optimization enabled notification arrives 10–20 minutes late. Reason — Doze Mode delays network ops, FCM uses "normal priority" by default. For financial notifications need explicit "priority": "high" in FCM payload, then message delivered via high-priority channel and wakes device.
iOS similar story with Background App Refresh — if user disabled it, background fetch won't work. Only reliable way — APNs push with content-available: 1 or interruption-level: time-sensitive.
Bot Notification Architecture
Bot generates event (position open/close, stop-loss hit, take-profit reached) → server handler creates payload → Firebase Admin SDK sends to FCM/APNs.
Minimal deal payload:
{
"notification": {
"title": "BTC/USDT ✅ Closed +2.3%",
"body": "Buy 0.05 BTC @ 67,420 → Sell @ 68,980"
},
"android": { "priority": "high" },
"apns": {
"headers": { "apns-priority": "10" },
"payload": { "aps": { "interruption-level": "time-sensitive" } }
},
"data": { "trade_id": "t_9182", "symbol": "BTCUSDT", "pnl": "2.31" }
}
data field for deep link — tap opens specific trade screen with details.
Notification Types and Priority
| Event | FCM Priority | APNs interruption-level |
|---|---|---|
| Stop-loss triggered | high | time-sensitive |
| Take-profit | high | time-sensitive |
| Position opened | high | active |
| Daily report | normal | passive |
| Exchange connection error | high | time-sensitive |
Separation matters: user can allow "critical" notifications even in "Do Not Disturb" — works via iOS Focus Filters and Android notification channels with IMPORTANCE_HIGH.
Client Side
On Flutter implement via firebase_messaging package. Important — handle three states correctly: foreground, background, terminated. In terminated state notification processed via FirebaseMessaging.instance.getInitialMessage() on next app start.
On React Native — @react-native-firebase/messaging, logic same.
Request permissions not on startup but on first bot-related action — conversion to permission significantly higher than cold start.
Timeline: integration into existing app — 3–7 days with ready bot backend.







