Skip to content

Push Notifications

  • GitHub stars for shinyorg/shiny
  • NuGet downloads for Shiny.Push
Frameworks
.NET
.NET MAUI
Blazor
Operating Systems
Android
iOS
macOS
Windows

Push notifications are server-driven notifications delivered via platform services (APNs on iOS / macOS, FCM on Android, WNS on Windows, Web Push on Blazor). Shiny provides a unified API that works across providers while giving you access to native capabilities.

PlatformProviderPackage
iOSAPNs (direct or via Firebase)Shiny.Push
macOSAPNsShiny.Push
AndroidFirebase Cloud MessagingShiny.Push
WindowsWindows Notification ServiceShiny.Push
Blazor WebAssemblyWeb Push (VAPID)Shiny.Push.Blazor
Shiny.PushNuGet package Shiny.Push
Shiny.Hosting.MauiNuGet package Shiny.Hosting.Maui

Add the intent filter for handling notification taps:

[Activity(
Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
LaunchMode = LaunchMode.SingleTop
)]
[IntentFilter(
new[] { Shiny.Push.ShinyPushIntents.NotificationClickAction },
Categories = new[] { "android.intent.category.DEFAULT" }
)]
public class MainActivity : MauiAppCompatActivity
{
}

IPushManager handles registration and token management.

IPushManager pushManager; // injected
// Request access and get token
var result = await pushManager.RequestAccess();
if (result.Status == AccessState.Available)
{
var token = result.RegistrationToken;
// Send token to your server
}
// Current tokens
var regToken = pushManager.RegistrationToken; // Provider token
var nativeToken = pushManager.NativeRegistrationToken; // Raw APNs/FCM token
// Unregister
await pushManager.UnRegister();

Implement IPushDelegate (or extend PushDelegate) to handle push events.

public class MyPushDelegate : PushDelegate
{
readonly ILogger<MyPushDelegate> logger;
public MyPushDelegate(ILogger<MyPushDelegate> logger)
{
this.logger = logger;
}
public override Task OnEntry(PushNotification notification)
{
// User tapped the notification
this.logger.LogInformation("Push tapped: {Title}", notification.Notification?.Title);
// Access data payload
foreach (var (key, value) in notification.Data)
{
this.logger.LogInformation("{Key}: {Value}", key, value);
}
return Task.CompletedTask;
}
public override Task OnReceived(PushNotification notification)
{
// Push received (background or foreground)
this.logger.LogInformation("Push received: {Title}", notification.Notification?.Title);
return Task.CompletedTask;
}
public override Task OnNewToken(string token)
{
// Token changed - send to your server
this.logger.LogInformation("New push token: {Token}", token);
return Task.CompletedTask;
}
public override Task OnUnRegistered(string token)
{
// Unregistered - notify your server
this.logger.LogInformation("Push unregistered: {Token}", token);
return Task.CompletedTask;
}
}
services.AddPush<MyPushDelegate>();

Tags allow you to target push notifications to specific groups of users. Tag support depends on your push provider.

IPushManager pushManager; // injected
if (pushManager.IsTagsSupport())
{
await pushManager.Tags.SetTags("premium", "news");
await pushManager.Tags.AddTag("sports");
await pushManager.Tags.RemoveTag("news");
var tags = pushManager.Tags.RegisteredTags;
await pushManager.Tags.ClearTags();
}
// Or use convenience extensions
await pushManager.TrySetTags("premium", "news");
var tags = pushManager.TryGetTags();

Implement IApplePushDelegate for iOS-specific control over notification presentation.

#if IOS
public class MyPushDelegate : PushDelegate, IApplePushDelegate
{
public UNNotificationPresentationOptions? GetPresentationOptions(PushNotification notification)
{
// Control how notifications appear when app is in foreground
return UNNotificationPresentationOptions.Banner |
UNNotificationPresentationOptions.Sound |
UNNotificationPresentationOptions.Badge;
}
public UIBackgroundFetchResult? GetFetchResult(PushNotification notification)
{
return UIBackgroundFetchResult.NewData;
}
}
#endif

Cast PushNotification to AndroidPushNotification for full control.

#if ANDROID
public override Task OnReceived(PushNotification notification)
{
if (notification is AndroidPushNotification androidPush)
{
// Use the default builder and send
androidPush.SendDefault(1001);
// Or customize the notification
var builder = androidPush.CreateBuilder();
builder
.SetContentTitle("Custom Title")
.SetSmallIcon(Resource.Mipmap.appicon);
androidPush.Notify(1001, builder);
}
return Task.CompletedTask;
}
#endif