CrossShovePlugin 9.0.0-alpha1
dotnet add package CrossShovePlugin --version 9.0.0-alpha1
NuGet\Install-Package CrossShovePlugin -Version 9.0.0-alpha1
<PackageReference Include="CrossShovePlugin" Version="9.0.0-alpha1" />
paket add CrossShovePlugin --version 9.0.0-alpha1
#r "nuget: CrossShovePlugin, 9.0.0-alpha1"
// Install CrossShovePlugin as a Cake Addin #addin nuget:?package=CrossShovePlugin&version=9.0.0-alpha1&prerelease // Install CrossShovePlugin as a Cake Tool #tool nuget:?package=CrossShovePlugin&version=9.0.0-alpha1&prerelease
CrossShovePlugin
Introduction
Welcome to the CrossShovePlugin - a C# Push Notification library currently for iOS (APNS) and Android (FCM).
Why is it called Cross Shove Plugin?
- Cross = Cross Platform
- Shove = Push
- Plugin = It's a MAUI Plugin
The plugin is responsible for
- Checking whether you have push permission
- Registering for push notifications
- handling the receipt of a push notification
- Basic - title and message
- Data - key value pairs
- Background (coming soon)
The plugin needs to communicate with our shove server (api.shoveserver.com). The server is responsible for
- Authorisation checks
- Registering devices
- Each device is given a unique ID so it doesn't matter whether Apple, Google or Microsoft suddenly provision a new push token for your customers device, the push server will ensure the details are updated.
- Sending push messages
- iOS - using the native Apple Push Notification Service (APNS)
- Android - using the Firebase TBD (FCM)
- WNS - Windows TBD
- Automatic de-registering - if a push token is deemed invalid (e.g. the user has uninstalled your app) then the push token is removed.
Important Notes
It is recommended to keep your iOS, Android and Windows application identifiers the same, otherwise you will need to create separate 'applications' in the Shove server portal and this will add complexity in your server app when sending push notifications to devices on different platforms, for example when sending a push notification you need to specify your application ID, so instead of using the following
com.mycompany.myappname.ios
com.mycompany.myappname.droid
com.mycompany.myappname.win
Try to consistently use
com.mycompany.myappname
History
We were using Microsoft AppCenter to send basic push notifications and we were very happy with this. Microsoft unfortunately planned to shut it down on December 31st, they extended that deadline to the middle of February.
The official replacement is Azure Notification Hubs. For one of our projects we have a lot of devices registered and that would cost us a minimum of £100 a month. The cost along with the fear they could drop notification hubs or change it in the future made us decide to write our own implementation.
This plugin enables independent software developers to get up and running with the least amount of cost and the simplest set up.
Our immediate goal was to reach feature-parity with our current use of AppCenter
- Request Push permission
- Register a device
- Send push to a device
Setup
A) Install the CrossShovePlugin NuGet
- Add the CrossShovePlugin NuGet to
- The shared / common project
- iOS
- Android
- UWP
- Don't forget to rebuid before you try to resolve your C# imports
B) Configure your mobile apps
For any project that you setup push notifications for there's a whole set of steps that's required and it's different per platform, please read these guides for each platform.
C) Initialise the CrossShovePlugin
For MAUI, you can put the following code snippet in your App.xaml.cs OnStart() method.
protected override void OnStart()
{
CrossShovePlugin.Current.Init(
publicAppKey: "my-PUBLIC-shove-key", // <-- Replace with your PUBLIC key
pushMessageEventHandler: (object sender, PushMessageEventArgs e) =>
{
MainPage.DisplayAlert(e.Title, e.Message, "Ok"); // <-- Basic push
}
);
}
D) Permission hooks for Android
In your MainActivity
you need to override the OnRequestPermissionsResult
method so that
the Shove library can be notified when the Notification permission has been enabled by
the user (only actually invoked on Android 13+).
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
Logger.Log(this, "OnRequestPermissionsResult invoked");
Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
// To inform Shove that Android has been granted permission for notifications
// on Android 13+
if (requestCode == ShovePlugin.PostNotificationsRequestCode)
{
ShovePlugin.Android13NotificationPermissionTaskCompletion?.SetResult(grantResults);
}
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
Logger.Log(this, "OnRequestPermissionsResult done");
}
Whenever a push notification is received a popup will be displayed to the user.
E) Listen to events
There are other initialisation delegates that you can optionally add during the intiialisation of the plugin:
- shoveDeviceRegistered - The simplest title and message (as shown in the code above)
- shovePushDataReceived - For when a data payload is also received
- shoveTokenRefreshed - To notify your app that a native push token has been collected
- shovePermissionChanged -
- shoveDeviceRegistered -
In addition you can register as a event subscriber from anywhere in your code via the CrossShovePlugin class, for example
public MyCarouselPage() {
CrossShovePlugin.ShoveTokenRefreshed += ( (object sender, string e) => {
// Do something to show this to the user
});
}
Each of those handlers are described in more detail below
Event - shoveDeviceRegistered
When a push notification is received you will get the notification payload data in this event.
On iOS by default you need to tap the notification to receive the data (TBD true?)
Event - shovePushDataReceived
When a push notification is opened you will receive the payload data in this event. This is ideal to navigate to other place in your app.
shovePushDataReceived: (object sender, PushDataEventArgs e) =>
{
MainPage.DisplayAlert(e.Title, e.Message + "Received Data!", "Ok");
}
Event - shoveTokenRefreshed
Please note that the token returned here is the native push token, it's for debugging purposes but you should not persist this on your server, instead if you require the unique Shove device ID then you can request it from the Plugin at any time (it doesn't change unless the app is re-installed, whereas the native push token can change multiple times).
pushTokenRefreshedHandler: (object sender, String e) =>
{
MainPage.DisplayAlert("Shove Demo", $"New native push token created:{e} The Shove unique device ID is '{CrossShovePlugin.GetDeviceId()}'", "Ok");
}
Event - shovePermissionChanged
Perhaps you have a user-interface that needs to render something different depending on whether the user has provided push notification permission, or not.
For example, in an on-boarding carousel you might want to hide the 'Next' button until the user has requested the appropriate permission. Alternatively you might want to hide a panel if the permission has already been granted.
By listening to the ShovePermissionChanged event you can update your own properties to reflect the latest permissions.
CrossShovePlugin.ShovePermissionChanged += CrossShovePlugin_ShovePermissionChanged;
...
private void CrossShovePlugin_ShovePermissionChanged(object sender, NotificationPermissionEnum e)
{
NextButtonEnabled = e.Equals(NotificationPermissionEnum.AUTHORIZED);
ShoveRequestPushPanel = !e.Equals(NotificationPermissionEnum.AUTHORIZED);
}
Event - shoveDeviceRegistered
Typically you can simply get the Shove Device ID from the plugin like this.
var ShoveDeviceToken = CrossShovePlugin.GetDeviceId();
Alternatively you can listen to registerDeviceReponseHandler to be notified when the Shove device ID is first assigned by the Shove Server.
Sending a push notification
The Shove server sends the push notifications using the APNS, FCM or WNS protocols, but your server is responsible for initiating the push.
Security / Public App Key / Private Server Key
Please note that the public app key is different to the private server key.
Public App Key - Must only be used in your mobile apps
Private Server Key - Must only be used when calling the shove server from your server over SSL
The Shove server will never let you send a push token without you providing your private key.
It's critical that you keep the private key secret by only passing it between your server and the shove server using a secure connection (SSL).
If you did use the private server key in your app then hackers could discover your private key and attempt to initiate push notification messages to your users without your permission.
One last time, NEVER use the private key from anywhere other than on your secure server using a secure connection over HTTPS.
Example server code
Here's an example server snippet that sends a push notification to a specific device.
Java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"DeviceId\":\"device-com.devology.dummy.app-2d2c6a30-5d41-45a9-9a4b-0d01af91357c\",\n \"Title\": \"MY TITLE\",\n \"SubTitle\": \"MY SUBTITLE\",\n \"Message\": \"MESSAGE BODY GOES HERE\", \n \"Data\": {\n \"id\": \"5ffb379d06f90e614690153d\"}");
Request request = new Request.Builder()
.url("https://api.shoveserver.com/api/SendPushNotification")
.method("POST", body)
.addHeader("PrivateServerKey", "your-private-server-key-goes-here")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build();
Response response = client.newCall(request).execute();
C# TBD
*TBD*
FAQs
- Can the server send to more than one device at a time - No, not yet.
The future
In the future we will look at adding
- Background events
- Analytics
- Tagging (e.g. adding tags to users then target them by those tags - for example based on their geographic location, interests, etc)
- More depending on feedback and availability
- Huawei HCM (Android FCM doesn't work on Huawei devices)
Licence
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0-android35.0 is compatible. net9.0-ios18.0 is compatible. |
-
net9.0-android35.0
- Microsoft.Maui.Controls (>= 9.0.0-rc.2.24503.2)
- Newtonsoft.Json (>= 13.0.3)
- Xamarin.Firebase.Messaging (>= 123.0.8)
- Xamarin.GooglePlayServices.Base (>= 118.1.0)
-
net9.0-ios18.0
- Microsoft.Maui.Controls (>= 9.0.0-rc.2.24503.2)
- Newtonsoft.Json (>= 13.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
9.0.0-alpha1 | 41 | 11/6/2024 |
(Not built for Win UI in this version)