Implementing Whale Alerts in Mobile App
Large $50M transaction passed in network — user learned about it 40 minutes later, after market already reacted. Such delay makes tracker useless. Whale Alert — real-time task where minute accuracy matters, and notification architecture affects product value.
Data Sources and Why It's Complex
Most teams start with public Whale Alert API (api.whale-alert.io) or alternatives — Glassnode, Nansen, CryptoQuant. Problem isn't data retrieval — it's delivering before competitors.
Classic approach: mobile client polls every 30 seconds. This drains battery, overloads server, and still gives 15–30 second delay. On Android it conflicts with Doze Mode — WorkManager postpones tasks when screen off.
Working approach differs:
- Server worker subscribes to WebSocket stream (
wss://stream.binance.com,wss://ws.blockchain.info/inv) or polls every 5–10 seconds - When detecting transaction above threshold (e.g., >500 BTC or >$1M USD) worker creates payload and sends via FCM (Android) and APNs (iOS) simultaneously
- Client receives notification in background, displays via
UNUserNotificationCenter(iOS) orNotificationCompat.Builder(Android)
On iOS important to set apns-priority: 10 for urgent notifications — otherwise APNs may buffer delivery until next device wake-up. Requires entitlement com.apple.developer.usernotifications.time-sensitive.
Filtering and Personalization on Client
User doesn't want notification about every $500K transaction — sets thresholds. Typical filter set:
- Minimum transaction amount (USD or native currency)
- Direction: only incoming to exchange, only outgoing, peer-to-peer
- Networks: BTC, ETH, SOL, TRX, etc.
- Watchlist addresses
These settings stored on server, tied to FCM topic or individual token. First option simpler for broadcast, second — more flexible for personalization. Practice uses hybrid: topics for common threshold events (whale_btc_1m) and individual tokens for watchlist addresses.
On app side implement filters via UNNotificationServiceExtension (iOS) — extension intercepts notification before display and can reject or modify based on local settings. On Android via FirebaseMessagingService.onMessageReceived() with manual call or skip NotificationManager.
Technical Implementation
Server stack: Node.js worker + Redis Pub/Sub for task distribution between instances + Firebase Admin SDK for sending.
For iOS use APNs via HTTP/2 directly (library node-apn or @parse/node-apn) — faster than FCM proxy. Latency difference small, but under high load (>10K devices) direct APNs more stable.
Notification payload contains minimum data — only what's needed for display and deep link:
{
"title": "🐋 BTC: 1,200 BTC → Binance",
"body": "$72.4M · 2 minutes ago",
"data": {
"tx_hash": "a1b2c3...",
"chain": "bitcoin",
"amount_usd": 72400000
}
}
Deep link opens transaction detail screen via Universal Links (iOS) or App Links (Android).
Delivery Monitoring
Firebase Console shows only basic stats. For production important to track:
- Delivery rate — percent successfully delivered (FCM Analytics)
- Time-to-deliver — time from event detection to device receipt
- Open rate — how many users tapped
For time-to-deliver use custom metric: server writes send timestamp in payload, client logs receipt timestamp and sends delta to analytics (Mixpanel or own ClickHouse).
Work Steps
- Audit data sources — select API, evaluate stream latency and reliability
- Server worker architecture — polling/WebSocket, duplicate handling, rate limiting
- FCM + APNs setup, obtain certificates/keys
- Client implementation — request permissions, handle tokens, deep linking
- User filter system — settings UI, server sync
- Test on real devices (Doze Mode, Background App Refresh)
- Monitoring and alerting
Timeline: 2 weeks for basic integration (ready backend + one stream) to 5–6 weeks for full development from scratch with custom filters and 5+ blockchain support.







