Skip to content
Client v5: BLE, BLE Hosting, HTTP, Jobs - Linux, MacOS, & Blazor Support! Full AOT, RX on BLE only & MANY other features! Power up!

Push (Server)

Server-side push notification dispatch for .NET. A provider-agnostic core with four built-in transports — direct APNs (token-based .p8 / ES256 over HTTP/2, no FCM dependency for Apple), FCM (HTTP v1, with multicast batching), Web Push (VAPID + RFC 8291), and WNS (Windows, modern Windows App SDK / Entra auth) — plus pluggable persistence (Shiny.DocumentDb), structured targeting, an interceptor pipeline, automatic dead-token pruning, multi-app keyed registration, and System.Diagnostics.Metrics telemetry. The whole library is AOT/trim-safe.

Frameworks
.NET
ASP.NET
Core (incl. APNs, FCM, Web Push & WNS)NuGet downloads for Shiny.Extensions.Push
DocumentDbNuGet downloads for Shiny.Extensions.Push.DocumentDb
  • Provider-agnostic core — one IPushManager; transports plug in as IPushProvider
  • Four transports in the box — direct APNs (.p8/ES256 over HTTP/2), FCM (HTTP v1), Web Push (VAPID + RFC 8291), and WNS (Windows App SDK / Entra auth) all ship in the core package; each is opt-in via AddApns / AddFcm / AddWebPush / AddWns
  • Structured, AOT-safe targeting — send to a user, tags/segments, explicit tokens, or broadcast
  • Rich payloads — title/body, badge, sound, deep link, collapse id, TTL, silent/background pushes, plus per-platform escape hatches (ApplePushOptions, AndroidPushOptions, WebPushOptions, WindowsPushOptions)
  • Automatic token hygiene — expired/invalid tokens are pruned; rotated tokens are applied back
  • Interceptors — localize, personalize, or suppress per device
  • Batching / FCM multicast — batch-capable transports deliver many devices per call (FCM: up to 500 per /batch request); on by default via IPushBatchProvider
  • Multi-app — keyed registrations serve several apps from one server
  • Metrics — counters + latency histogram via System.Diagnostics.Metrics (OpenTelemetry-ready)
  • Pluggable persistence — in-memory out of the box, or Shiny.DocumentDb on any backend

Install the core package — it includes the APNs, FCM, Web Push and WNS transports — and, optionally, a persistence package:

Terminal window
dotnet add package Shiny.Extensions.Push
dotnet add package Shiny.Extensions.Push.DocumentDb # optional; defaults to in-memory

Register the service:

using Shiny.Extensions.Push;
using Shiny.Extensions.Push.Apns;
using Shiny.Extensions.Push.DocumentDb;
using Shiny.DocumentDb.Sqlite;
builder.Services.AddPushNotifications(push =>
{
push.AddApns(o =>
{
o.TeamId = "ABCDE12345";
o.KeyId = "KEY1234567";
o.BundleId = "com.example.app";
o.PrivateKeyPath = "AuthKey_KEY1234567.p8"; // or o.PrivateKey = "<PEM contents>"
});
// Persistence (omit to use the in-memory repository)
push.UseDocumentDb(o => o.DatabaseProvider = new SqliteDatabaseProvider("Data Source=push.db"));
});

Register a device when your app reports its token:

await pushManager.RegisterDevice(new DeviceRegistration
{
DeviceToken = "<apns-device-token>",
Platform = DevicePlatform.iOS,
DeviceId = "install-guid", // stable identity across token rotation
UserIdentifier = "user-42",
Tags = ["beta", "sports"],
Environment = PushEnvironment.Production // APNs tokens are environment-specific
});

Send:

var result = await pushManager.SendToUser("user-42", new PushNotification
{
Title = "Goal!",
Message = "Your team just scored",
Badge = 1,
DeepLink = "app://match/123"
});
// result.BatchId, result.Sent, result.Failed, result.TokensRemoved, result.Skipped

Next: Sending, APNs, Persistence, Metrics.