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.

Critical Requirement

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
Important

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:

Peer wants to sync Push sent via FCM App wakes LiteP2P connects Data synced

Flow Details

  1. Peer A wants to send data to Peer B
  2. Peer A sends a push notification to Peer B via LiteP2P relay
  3. Peer B's app wakes up and calls onPushReceived()
  4. LiteP2P establishes direct P2P connection
  5. Data is exchanged directly between peers
  6. 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

Best Practices

Use push only for wake signals, never for data
Handle token refresh properly
Use high-priority sparingly to avoid FCM throttling
Test on devices without Google Play Services
Implement fallback for push delivery failures