Skip to content
Shiny.NET
Commercial SupportGuaranteed response times on Shiny bug fixes, straight from the maintainers. Plans from US$1,500 a year.See the plans

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
Changed files
  • MyApp/
MyApp.csproj
MyApp.csproj
1<Project Sdk="Microsoft.NET.Sdk.Web">2​3    <PropertyGroup>4        <TargetFramework>net10.0</TargetFramework>5        <Nullable>enable</Nullable>6        <ImplicitUsings>enable</ImplicitUsings>7        <OpenApiDocumentsDirectory>.</OpenApiDocumentsDirectory>8        <MicrosoftVersion>10.0.14</MicrosoftVersion>9        <ShinyExtensionsLocalizationVersion>2.0.1</ShinyExtensionsLocalizationVersion>10        <ShinyExtensionsReflectorVersion>6.0.1</ShinyExtensionsReflectorVersion>11        <ShinyExtensionsStoresVersion>6.0.1</ShinyExtensionsStoresVersion>12        <ShinyExtensionsDIVersion>6.0.1</ShinyExtensionsDIVersion>13        <MyAppVersion>1.0.0</MyAppVersion>14        <ShinyDocumentDbVersion>14.1.0</ShinyDocumentDbVersion>15        <MediatorVersion>6.12.0</MediatorVersion>16        <NpgsqlVersion>10.0.3</NpgsqlVersion>17        <ScalarVersion>2.18.3</ScalarVersion>18    </PropertyGroup>19​20    <ItemGroup>21        <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="$(MicrosoftVersion)" />22        <PackageReference Include="Microsoft.Extensions.ApiDescription.Server" Version="$(MicrosoftVersion)"/>23        <PackageReference Include="Shiny.AspNet.WebHosting" Version="$(MyAppVersion)" />24        <PackageReference Include="Shiny.Extensions.Push" Version="3.0.0-beta-0008" />25​26    </ItemGroup>27</Project>
Transport Platform setup Client app setup
APNs Apple Developer setup Apple
FCM Firebase setup Android
WNS Microsoft setup Windows
Web Push VAPID keys Web Push
Core (incl. APNs, FCM, Web Push & WNS) NuGet downloads for Shiny.Extensions.Push
DocumentDb NuGet downloads for Shiny.Extensions.Push.DocumentDb
Feature Description
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
Event receivers observe the send lifecycle (batch start/finish, per-device sent/failed) for telemetry, receipts, or dead-letter capture
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: Client Apps, Sending, APNs, FCM, WNS, Web Push, Persistence, Metrics.