FS.Push
10.2.0
dotnet add package FS.Push --version 10.2.0
NuGet\Install-Package FS.Push -Version 10.2.0
<PackageReference Include="FS.Push" Version="10.2.0" />
<PackageVersion Include="FS.Push" Version="10.2.0" />
<PackageReference Include="FS.Push" />
paket add FS.Push --version 10.2.0
#r "nuget: FS.Push, 10.2.0"
#:package FS.Push@10.2.0
#addin nuget:?package=FS.Push&version=10.2.0
#tool nuget:?package=FS.Push&version=10.2.0
Push Notification Service
Overview
This NuGet package provides a convenient and efficient way to send push notifications using Firebase's HTTP v1 API. The service allows you to send push notifications to devices or topics by making REST API calls, following the updated HTTP v1 guidelines from Firebase documentation. This package is ideal for .NET 8, .NET 9 and .NET 10 applications and offers flexibility for configuring notification content, priority, TTL, and other parameters.
Features
- Cross-platform support for .NET 8, .NET 9 and .NET 10
- Push notifications using Firebase's HTTP v1 API (no dependency on FCM or HPNS)
- Supports both topic-based and single-device token notifications
- High flexibility with various configuration options such as priority, TTL, and notification content
- Easy integration with minimal setup required
Installation
To get started, install the NuGet package via the following command:
dotnet add package FS.Push
or search for FS.Push in the NuGet Package Manager.
Example usage
This example demonstrates how to send a push notification using both Firebase and Huawei services. If you wish to send a notification only through Firebase, set the Huawei object to null. Similarly, for Huawei-only notifications, set the Firebase object to null.
string title = "This is title of push";
string body = "This is a message body";
Dictionary<string, string> customData = new()
{
{ "item1", "X" },
{ "item2", "0" },
{ "item3", "value1" }
};
PushModel pushModel = new PushModel()
{
Settings = new PushSettingsModel()
{
Firebase = new PushFirebaseSettingsModel()
{
ClientEmail = "firebase_client_email",
PrivateKey = "firebase_project_id",
ProjectId = "firebase_private_key",
Topics = ["topic1", "topic2"]
},
Huawei = new PushHuaweiSettingsModel()
{
ClientId = "huawei_client_id",
ClientSecret = "huawei_client_secret",
Topics = ["topic1", "topic3", "topic4"]
}
},
Message = new PushMessageModel()
{
Priority = "high",
Ttl = "86400s",
Category = "category",
Sound = "default",
ConditionType = ConditionType.OR, // optional, defaults to Default
Notification = new PushNotificationModel()
{
Title = title,
Body = body
},
Data = customData
}
};
List<PushResultModel> results = await PushService.SendAsync(pushModel);
foreach (PushResultModel result in results)
{
Console.WriteLine($"Provider: {result.Provider}");
Console.WriteLine($"Status Code: {result.StatusCode}");
Console.WriteLine($"Topics or Tokens: {result.TopicsOrTokens}");
Console.WriteLine($"Success: {result.Success}");
Console.WriteLine($"Response: {result.Response}");
if (!string.IsNullOrEmpty(result.Model))
Console.WriteLine($"Debug Info: {result.Model}");
Console.WriteLine();
}
Topic targeting (ConditionType)
The ConditionType property on PushMessageModel controls how the topics array is targeted (it applies to both Firebase and Huawei, and is ignored when sending to tokens):
| Value | Behavior |
|---|---|
Default |
One push is sent to each topic in the array (one request per topic). |
OR |
A single push to devices subscribed to any topic: 'topic1' in topics \|\| 'topic2' in topics. |
AND |
A single push to devices subscribed to all topics: 'topic1' in topics && 'topic2' in topics. |
The topics arrays must contain only topic names — no logical operators.
Firebase Authentication
- ClientEmail: Your Firebase client email
- ProjectId: Your Firebase project ID
- PrivateKey: Your Firebase private key
- Topics: List of topics to target for push notifications
Huawei Authentication
- ClientId: Your Huawei client ID
- ClientSecret: Your Huawei client secret
- Topics: List of topics for Huawei push notifications
Changelog
[10.2.0]
- Added the
ConditionTypeenum (Default,AND,OR) and aConditionTypeproperty onPushMessageModelto control how the topics array is targeted, for both Firebase and Huawei:Default(default): one push is sent to each topic (previous default behavior).OR: a single push to devices subscribed to any topic ('a' in topics || 'b' in topics).AND: a single push to devices subscribed to all topics ('a' in topics && 'b' in topics).
- Breaking: the topics array must now contain only topic names — the previous
"||"sentinel element is no longer recognized. UseConditionType = ConditionType.ORinstead. - Removed dead code: the unused
internal PushAndroidConfigModel.Validate()method and the never-setinternal Badgeproperty on the APNS payload (both unreachable from outside the assembly).
[10.1.2]
- Fix for the RSA
ObjectDisposedExceptionon consecutive pushes: the Firebase JWT is now signed manually (RS256 viaRSA.SignData) instead of usingJwtSecurityTokenHandler/RsaSecurityKey. This removes the Microsoft.IdentityModelCryptoProviderFactorysignature-provider cache, which reused a disposed RSA across calls (the 10.1.1CacheSignatureProviders = falseworkaround was not sufficient). - Removed the
System.IdentityModel.Tokens.Jwtdependency (no longer needed).
License
MIT License
Copyright (c) 2019 FRΛƝCƎƧCØ ƧØЯRƎƝTIƝØ
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Support
If you find this package useful, feel free to support the author by offering a coffee or donating with PayPal
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.