Push Notifications (Mandatory Wake Mechanism)
Push notifications are the only reliable way to wake your application on modern Android. This guide explains how to integrate push notifications with LiteP2P.
Android does NOT allow background polling. Without push notifications, your app cannot reliably receive P2P messages when in background.
Why Push Notifications?
Push notifications solve the fundamental problem of waking a sleeping app:
- Wake the app reliably – Even when the app is killed
- Bypass Doze – High-priority messages break through power saving
- Battery-efficient – Uses shared system connection
- Works across all OEMs – Consistent behavior
Supported Providers
| Provider | Status | Best For |
|---|---|---|
| FCM (Firebase Cloud Messaging) | ✅ Recommended | Most apps, best reliability |
| UnifiedPush | ✅ Supported | Privacy-focused, self-hosted |
Push is NOT data transport. Push notifications only signal "wake and sync". Never send P2P data through push – it's for signaling only.
FCM Setup
Firebase Cloud Messaging is the recommended push provider for most applications.
1. Add Firebase to Your Project
// project-level build.gradle
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.4.0'
}
}
// app-level build.gradle
plugins {
id 'com.google.gms.google-services'
}
dependencies {
implementation 'com.google.firebase:firebase-messaging:23.4.0'
}
2. Create Messaging Service
class LiteP2PMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// Check if this is a LiteP2P wake signal
if (remoteMessage.data["type"] == "litep2p_sync") {
// Wake LiteP2P and sync
LiteP2P.getInstance().onPushReceived(remoteMessage.data)
}
}
override fun onNewToken(token: String) {
// Register token with LiteP2P
LiteP2P.getInstance().registerPushToken(token)
}
}
3. Register in Manifest
<service
android:name=".LiteP2PMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
4. Configure LiteP2P
val config = PeerConfig.Builder()
.setAppId("your-app-id")
.setPushProvider(PushProvider.FCM)
.build()
LiteP2P.initialize(context, config)
// Get and register token
FirebaseMessaging.getInstance().token.addOnSuccessListener { token ->
LiteP2P.getInstance().registerPushToken(token)
}
UnifiedPush Setup
UnifiedPush is an open alternative for privacy-conscious applications.
// Add dependency
implementation 'org.unifiedpush.android:connector:2.1.1'
// Register with UnifiedPush
class MyUnifiedPushReceiver : MessagingReceiver() {
override fun onNewEndpoint(context: Context, endpoint: String, instance: String) {
// Register endpoint with LiteP2P
LiteP2P.getInstance().registerPushEndpoint(endpoint)
}
override fun onMessage(context: Context, message: ByteArray, instance: String) {
// Wake LiteP2P
LiteP2P.getInstance().onPushReceived(message)
}
}
Push-Wake Flow
Here's how LiteP2P uses push notifications:
Flow Details
- Peer A wants to send data to Peer B
- Peer A sends a push notification to Peer B via LiteP2P relay
- Peer B's app wakes up and calls
onPushReceived() - LiteP2P establishes direct P2P connection
- Data is exchanged directly between peers
- Connection closes, app returns to sleep
High-Priority Messages
For immediate wake-up, use high-priority FCM messages:
// Server-side (when triggering wake)
{
"to": "device_token",
"priority": "high",
"data": {
"type": "litep2p_sync",
"peer_id": "sender_peer_id"
}
}
High-priority messages:
- Wake the device from Doze
- Give the app ~10 seconds of execution time
- Should be used sparingly to avoid throttling