Self-hosted push SDK — no Firebase

Deliver notifications to Android and Windows apps straight from your Alpha panel — no Firebase, no Google Play Services, no third-party push. Devices long-poll /v1/inapp/poll and show notifications in real time.

Android OS rule: real-time delivery while the app UI is closed needs the SDK’s foreground service running (it shows a low-priority “listening” notification). That’s the only no-Firebase way on Android. Windows has no such limit.

Android — AlphaPush.kt

  1. Copy AlphaPush.kt into your project (package com.alphaxp.push).
  2. Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>            <!-- Android 13+ -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/> <!-- Android 14+ -->

<service android:name="com.alphaxp.push.AlphaPushService"
         android:foregroundServiceType="dataSync" android:exported="false"/>
  1. Depend on AndroidX core: implementation("androidx.core:core-ktx:1.13.1").
  2. Ask for the notification permission on Android 13+, then start it once (e.g. after login):
AlphaPush.start(applicationContext, "__ALPHA_API_BASE__")

The device registers itself and starts receiving. Notifications with a url open it on tap.

Windows — alpha-push.ps1

powershell -ExecutionPolicy Bypass -File alpha-push.ps1 -BaseUrl "__ALPHA_API_BASE__"

Nicer toasts: Install-Module BurntToast -Scope CurrentUser (falls back to a tray balloon). Run at logon with a Scheduled Task:

$a = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -ExecutionPolicy Bypass -File `"$PWD\alpha-push.ps1`" -BaseUrl __ALPHA_API_BASE__"
Register-ScheduledTask -TaskName "AlphaPush" -Trigger (New-ScheduledTaskTrigger -AtLogOn) -Action $a

The API (implement in any language)

CallPurpose
POST /v1/inapp/register {platform,name}→ {device_id, device_key} (store them)
GET /v1/inapp/poll?device=&key=&since=&wait=25long-poll → {notifications[], now}; reconnect with since=now
GET /v1/inapp/feed?device=&key=full inbox + unread count
POST /v1/inapp/read {device,key,id}mark read (id:"all" clears all)

Send from the panel: Notifications → In-app (pick platforms, compose, send). Long-poll holds one server worker per connected device — fine for a modest fleet; for very large audiences FCM (shared OS channel) is the scale/battery-efficient path.