Skip to content

Getting Started

Push notifications come in so many flavours these days. The community needed one way of doing things, but the ability to swap providers in and out at will. The reason, push providers, aside from native have been dropping like flies the last several years. The latest to go was AppCenter which it turns out the Xamarin community was heavily invested in.

Native push is the root of all other push providers. It works at the native OS level and is usually feeding other providers like Azure Notification Hubs and Firebase. As such, the setup instructions found within this document generally apply to all.


General OS setup is mostly the same on all platforms, but please review the specific provider you intend to use from the menu for more information


Android Setup

Android has two options for configuration.

Option 1 - google-services.json

You can download the google-services.json file from Firebase, you can place it in the Platforms/Android part of your MAUI project.

Next, open your csproj file and add the following:

<GoogleServicesJson Include="Platforms\Android\google-services.json" />
<!--If your project is having trouble picking up the json file, add this package as it contains the necessary msbuild tasks to include this file-->
<PackageReference Include="Xamarin.GooglePlayServices.Basement" Version="" />

Options 2 - Configuration Variables

You still need to download the google-services.json, but this time, open it in a text editor

// mauiprogram.cs or your host building portion
new Shiny.Push.FirebaseConfig(
false, // false to ignore embedded configuration
"1:111111111111", // appid
"1:111111111111:android:1101a1bc1111111d", // sender id/project_number
"shiny-sample", // project_id
"random string" // api_key

With 1 of these options now in place, follow the base setup instructions above


Look to each appropriate provider to see setups for each. The most important function otherwise, is RequestAccess shown below which will give you the push notification token that you can send to your backend.

All providers use the native implementations on the platform to some degree, as such, you will always need to call

using System;
using System.Threading.Tasks;
using Shiny;
using Shiny.Push;
public class PushRegistration
public async Task CheckPermission()
var push = Host.Current.Services.GetService<IPushManager>();
var result = await push.RequestAccess();
if (result.Status == AccessState.Available)
// good to go
// you should send this to your server with a userId attached if you want to do custom work
var value = result.RegistrationToken;

Background Delegate

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Shiny.Push;
public class PushDelegate : IPushDelegate
public async Task OnEntry(PushEntryArgs args)
// fires when the user taps on a push notification
// please read specific android documentation below on how to make this work
public async Task OnReceived(IDictionary<string, string> data)
// fires when a push notification is received
// iOS: set content-available: 1 or this won't fire
// Android: Set data portion of payload
public async Task OnNewToken(string token)
// fires when a push registration token change is set by the operating system or provider
// also fires with RequestAccess value changes (or initial request)
public async Task OnUnRegistered(string token)
// fires when IPushManager.UnRegister is called
// or on startup when permissions are denied to push


Like other modules in Shiny, there are certain providers that support additional feature sets. Push really only has 1 extra, tagging.

The following providers, support tagging

  • Azure Notification Hubs
  • Firebase
  • Android Firebase (Native)
var push = Host.GetService<IPushManager>();
if (push.Tags == null)
// tags are not supported
else {
// current tags
var tags = push.Tags.RegisteredTags;
// clears all tags
await push.Tags.ClearTags();
// replace all tags with new set
await push.Tags.SetTags("tag1", "tag2");
// remove a tag
await push.Tags.RemoveTag("tag3");
// add a new tag
await push.Tags.AddTag("tag4");


No matter what mechanism you use in Push (both iOS & Android), the platform always rules push. For Android, everything is built on Firebase.

To get push entry delegate events to fire, you must add the following an intent filter as shown below to one (likely your main activity) activities

using Android.App;
using Android.Content.PM;
namespace YourNamespace;
Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges =
ConfigChanges.ScreenSize |
ConfigChanges.Orientation |
ConfigChanges.UiMode |
ConfigChanges.ScreenLayout |
ConfigChanges.SmallestScreenSize |
new[] {
Categories = new[] {
public class MainActivity : MauiAppCompatActivity


iOS is generally pretty straight forward, but does require a few extra steps shown at the top of this page in the library builder.

Customizing iOS Responses

Your push delegate can implement the IApplePushDelegate interface to customize the presentation options and background fetch result. The following is an example of how to do this:

#if IOS
using UIKit;
using UserNotifications;
public partial class MyPushDelegate : Shiny.Push.IPushDelegate
// .. left empty for brevity
#if IOS
public partial class MyPushDelegate : Shiny.Push.IApplePushDelegate
// this is only used in a foreground call
public UNNotificationPresentationOptions? GetPresentationOptions(PushNotification notification)
return UNNotificationPresentationOptions.Alert;
// this is executed on any content-available push notification
public UIBackgroundFetchResult? GetFetchResult(PushNotification notification)
return UIBackgroundFetchResult.NewData;
## Android
Please ensure to read [Firebase Cloud Messaging Documentation]( for how to implement
server side code.
With all AddPush registrations, we allow you to pass a Firebase Android argument that allows you to create a default channel for your notifications. You must either
include the CHANNEL with your push payload or set the default channel in your AndroidManifest.xml like so: