andrei-m-code / net-core-push-notifications Goto Github PK
View Code? Open in Web Editor NEWLightweight .NET Core Push Notifications for Android, iOS and Web
License: MIT License
Lightweight .NET Core Push Notifications for Android, iOS and Web
License: MIT License
How to send a message to multiple devices (token) both iOS and Android like PushSharp library did?
https://github.com/andrei-m-code/net-core-push-notifications/blob/master/CorePush/Apple/ApnSender.cs#L49
Can use CancellationToken?
I was trying to used it through Docker container, but I got SSL validation error
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure. at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception) at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest) --- End of stack trace from previous location where exception was thrown --- at System.Net.Security.SslStream.ThrowIfExceptional() at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result) at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult) at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__65_1(IAsyncResult iar) at System.Threading.Tasks.TaskFactory
1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action
1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean allowHttp2, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task
1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)`
Hi,
Using this code:
string p8Key = ReadResource("AuthKey_XXXXXXX.p8");
var settings = new ApnSettings()
{
AppBundleIdentifier = "com.hankinsoft.appwage",
ServerType = ApnServerType.Development,
TeamId = "XXXXXXX",
P8PrivateKeyId = "XXXXXXX",
P8PrivateKey = p8Key
};
string deviceToken = "<base64 encoded device token>";
using (HttpClient httpClient = new HttpClient())
{
var apn = new ApnSender(settings, httpClient);
var notification = new AppleNotification()
{
Aps = new AppleNotification.ApsPayload()
{
AlertBody = "Reports are now available",
ContentAvailable = true
}
};
apn.SendAsync(notification, deviceToken).Wait();
} // End of httpClient
And notification being:
public class AppleNotification
{
public class ApsPayload
{
[JsonProperty("alert")]
public string AlertBody { get; set; }
[JsonProperty("content-available")]
public bool ContentAvailable { get; set; }
}
// Your custom properties as needed
[JsonProperty("aps")]
public ApsPayload Aps { get; set; }
}
I receive the error:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
I'm not exactly sure what is not a valid Base-64 string. Is there any way to get more information about this?
I'm developing an ASP.NET API on macOS and I'm running it on Linux. When trying to push a notification I'm receiving an exception that WinCNG is not supported.
Is there a way I can work around this somehow?
When using apn.SendAsync, I got this error: Error 12175 calling WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, 'A security error occurred'. Could you please help? Thank you.
ImportPkcs8PrivateKey
requires the user profile be loaded, which is not true on shared tier (in Azure or other services) - it fails with an exception.
See the following issue for details:
aspnet-contrib/AspNet.Security.OAuth.Providers#358
(It works as expected on previous versions)
Hi! Is this library compatible with .net framework 4.7.2? Thanks!
Hello.
Thank you for your library.
Do you have solution for .net core 2.2?
I see that suggested approach is to create and dispose sender for each batch. However, each sender creates separate HttpClient, which is a bad thing, as might lead to sockets starvation.
I would like to inject my own instance of HttpClient created via HttpClientFactory (see here) to avoid this issue.
How to subscribe to topic?
How to add user to group?
1.)The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters
2.)P8 private key - have general p8 file , how to insert on asp core ?
Hi ,
Please can you tell me how can i distinguish between fem token which i received it is belongs to iOS or android
thanks
Hello!
Thank you for your library.
I tried to add vibration to notification for android (sound works, but vibration not).
My classes:
internal class AndroidNotification
{
public class Notification1
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
[JsonProperty("android_channel_id")]
public string AndroidChannelId { get; set; } = "id1";
[JsonProperty("sound")]
public string Sound { get; set; } = "default";
}
public class DataPayload
{
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("body")]
public string Body { get; set; }
[JsonProperty("sound")]
public string Sound { get; set; } = "default";
}
[JsonProperty("notification")]
public Notification1 Notification { get; set; }
[JsonProperty("priority")]
public string Priority { get; set; } = "high";
[JsonProperty("data")]
public DataPayload Data { get; set; }
}
var notification = new AndroidNotification
{
Notification = new AndroidNotification.Notification1
{
Body = message,
Title = title
},
Data = new AndroidNotification.DataPayload
{
Body = message,
Title = title
}
};
await fcm.SendAsync(token, notification);
I get notification with sound but without vibration.
I found this links
https://firebase.google.com/docs/cloud-messaging/migrate-v1
https://firebase.google.com/docs/cloud-messaging/send-message#c_2
https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#AndroidNotification
And I will try send this format via your library:
{
"message":{
"token":"MY_TOKEN",
"notification":{
"title":"Test",
"body":"Test message from server"
},
"android":{
"notification":{
"sound":"default",
"title":"Test",
"body":"Test message from server"
}
}
}
}
Now I recieve notification with sound and vibration, but without Title and Body.
Could you help me how send notification with Title, Body, Sound and Vibration via your Library which use legacy Firebase API?
It works in version after v3.
Do you recommend the use of Parallel.ForEach
for send message in APN?
Would it be possible to extend your fcm/apn senders logic with knowledge about provider responses as PushSharp library does?
GCM example reference:
https://github.com/Redth/PushSharp/blob/master/PushSharp.Google/GcmServiceConnection.cs
Thanks for your efforts!
According to documentation,
IMPORTANT 2: APN sender uses WinHttpHandler to send HTTP/2 requests which makes it usable only on Windows OS unfortunately. Once there is a cross-platform version or HttpClient will support HTTP/2, it will be migrated.
However I see you are no longer using WinHttpHandler and according to below link on core 3.0 it should support HTTP/2 , that means this lib can be used on linux with core 3.0 ?
https://github.com/dotnet/corefx/issues/23518#issuecomment-528120244
I can't use the current implementation of refreshing the JWT tokens because
a) I'm implementing an Azure function and this could scale up, each having their own isolated in-memory JWT tokens
b) The JWT tokens can be revoked at any time, so if there's a 403 response they should be cleared and re-attempted much earlier than their planned expiry
I have a fork where I'm hoping to contribute back to your plugin, but I've never done this before, so I'm submitting this issue in the hope I can attach the changes to it afterwards.
Hi,
Great work. Though I have been trying for a couple of days using it with no luck. I made sure all is ok in my code including server id, token.. I tried my own simpler code and it worked.
Can you guide me please how to call "SendAsync" for example? I doubt that I'm not using the Payload/Notification correctly.
Appreciated.
Here is a sample of my code:
String serverId = "xyz"; //from FCM console
String senderId = "xyz"; //from FCM console
String deviceToken = "xyz"; //from my device (which i receive notificaiton from above serverId)
GoogleNotification notification1 = new GoogleNotification();
notification1.Data = new GoogleNotification.DataPayload();
notification1.Data.Message = "some message";
notification1.Priority = "high";
using (var fcm = new FcmSender(serverId, senderId))
{
await fcm.SendAsync(deviceToken, notification1);
}
Could we create an interface for ApnSender?
To send notification to android device, where do I get fcmReceiverToken?
Also, is there any way to just use one code part to send notification to both iOS and Android?
Hi ,
Please can you tell me how can i distinguish between fem token which i received it is belongs to iOS or android
thanks
Hello anyone. I download your project with test. I fill all settings of my apn from firebase for IOS.
Then i try to send push notification and i always get BadDeviceToken.
In the firebase console with that token i got push notification on my phone successfully.
Please, help me, what i do wrong ?
Starting from March 2020, FCM stopped creating legacy server keys. Existing legacy server keys will continue to work, but we recommend that you instead use the newer version of key labeled Server key in the Firebase console.
https://firebase.google.com/docs/cloud-messaging/auth-server#windows
It looks like the new keys are not working.
Perhaps I have not completely figured out your package.
Now I have an error
System.FormatException : The format of value 'key=AAAAmqYgomQ:APA91bHp...7NTOizGXhN1K1TkTFw' is invalid.
How do I get the token. It seems to be ambiguously named as device id. If you can give an example of retrieving the token before invoking the API, that would be of great help.
Hello!
Currently CorePush hardcodes the FCM Url for sending requests to the FCM API here: https://github.com/andrei-m-code/net-core-push-notifications/blob/master/CorePush/Google/FcmSender.cs#L16
This makes it hard for us to change where the request is sent to (for example to https://webhook.site/ for testing purposes).
FcmSender
takes an HttpClient
from the user of the library. Wouldn't it make more sense to use the HttpClient.BaseAddress
property from the client as the destination for the requests rather than a hard coded URL?
If this is agreeable we can put out a PR for this.
It seems to me that we can keep the following cached in memory - headerBase64
and dsa
- in ApnSender.CreateJwtToken
.
Is there a reason not to? Or did you just not get to it yet?
Hello,
I am having issues when calling the method SendAsync, I get the exception bellow. The method gets called but I have no response, can you advice please?
We have <TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
using the service
var sender = new ApnSender(_settings, _httpClient);
var status = await sender.SendAsync(ReturnMsgInJObject(pushMessage), deviceToken);
This is the exception I get when I am debugging - tried to upgrade version of .net framework to 4.8 and it didnt help
System.TypeLoadException: Could not resolve type with token 01000016 from typeref (expected class 'System.Security.Cryptography.ECParameters' in assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51')
at CorePush.Apple.ApnSender.CreateJwtToken () [0x0008a] in <42ebfc7367d540908a427353c242a75a>:0
at CorePush.Apple.ApnSender.<GetJwtToken>b__8_0 (System.String _) [0x00000] in <42ebfc7367d540908a427353c242a75a>:0
at System.Collections.Concurrent.ConcurrentDictionary`2[TKey,TValue].GetOrAdd (TKey key, System.Func`2[T,TResult] valueFactory) [0x00034] in /Users/builder/jenkins/workspace/build-package-osx-mono/2020-02/external/bockbuild/builds/mono-x64/external/corefx/src/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs:1002
at CorePush.Apple.ApnSender.GetJwtToken () [0x00010] in <42ebfc7367d540908a427353c242a75a>:0
at CorePush.Apple.ApnSender.SendAsync (System.Object notification, System.String deviceToken, System.String apnsId, System.Int32 apnsExpiration, System.Int32 apnsPriority, System.Boolean isBackground, System.Threading.CancellationToken cancellationToken) [0x00086] in <42ebfc7367d540908a427353c242a75a>:0
Please, let me know if you need anything else.
Have a nice day
Wanted to check if it allow to add icon for the push message? Which can display in mobile device message with icon?
The documentation says:
For security, APNs requires you to refresh your token regularly. Refresh your token no more than once every 20 minutes and no less than once every 60 minutes. APNs rejects any request whose token contains a timestamp that is more than one hour old. Similarly, APNs reports an error if you recreate your tokens more than once every 20 minutes.
I'm reading the code but I cannot see how this is handled.
I guess we need do to something like:
Store the token in a static object after the first instantiation of ApnSender, then provide this saved token next time, and recreate the token if older than 60 mins...
It would also be nice to be able to:
This since I guess I need to use the same token for all concurrent running applications in order to obey the "no more then 20 minutes" rule....
Hello in the documentation I read that the constructor that previously accepted two strings is now:
var fcm = new FcmSender (settings, httpClient);
it is not clear to me how these objects should be initialized
Old Code:
using (var fcm = new FcmSender(config["ServerKey"], config["SenderId"]))
{
await fcm.SendAsync(deviceId, notification);
}
New Code:
FcmSettings sett = new FcmSettings();
sett.SenderId = config["SenderId"];
sett.SenderId = config["ServerKey"];
FcmSender fcm = new FcmSender(sett, new System.Net.Http.HttpClient());
I don't know if that's correct.
The using clause cannot be used because the object is not disposable.
What is the httpclient object for and how should it be instantiated?
From the guideline, I didn't see how to send multiple push notifications at a time. Could you please show me how to do that? Thank you.
I have installed the nuget package in my .net framework 4.7.2 backend and gets this response Only HTTP/1.0 and HTTP/1.1 version requests are currently supported, when calling apn.SendAsync. I can see in your code that you set the http request message version to 2: message.Version = new Version(2, 0); What can I do to fix my problem ? B.r. Jan Lange
Hello,
On "GetEllipticCurveAlgorithm" function of "AppleCryptoHelper", it gives error at "ECDsa.Create" call:
The specified key parameters are not valid. Q.X and Q.Y are required fields. Q.X, Q.Y must be the same length. If D is specified it must be the same length as Q.X and Q.Y for named curves or the same length as Order for explicit curves.
Lengths of
keyParams.D.ToByteArrayUnsigned()
q.XCoord.GetEncoded()
q.YCoord.GetEncoded()
are
31, 32 and 32 respectively.
I've filled all
AppBundleIdentifier
P8PrivateKey
P8PrivateKeyId
ServerType
TeamId
information corretly.
What may the be problem?
Regards,
Kindly provide the option of apns-push-type in sendAsync method. This way we can pass the apns-push-type to "voip" for voip push. This need to be sent in header of request.
Hello, I just received an email from Apple asking about updating the certificate. Do we need to do anything to accommodate this change when using this nuget package? Thanks.
Below is the email:
On March 29, 2021, token and certificate-based HTTP/2 connections to the Apple Push Notification service must incorporate the new root certificate (AAACertificateServices 5/12/2020) which replaces the old GeoTrust Global CA root certificate. To ensure a seamless transition and to avoid push notification delivery failures, verify that both the old and new root certificates for the HTTP/2 interface are included in the Trust Store of each of your notification servers before March 29.
Note that Apple Push Notification service SSL provider certificates issued to you by Apple do not need be to updated at this time.
When I send to apn I get error:
The server returned an invalid or unrecognized response.
at System.Net.Http.HttpConnection.FillAsync()
at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
Hi,
We want to use your module for one project. Can you tell us what the license is?
Can you add a open source license
Thanks,
Xuan
hi dear ,
with your code only i can send alert notification without background fetch content , kindly help me to solve this issue , even i set apns-push-type = background but i still not receive it , only receive alert when i change apns-push-type to alert but no silent push notification. my payload is
{
"aps" : {
"alert" :
{
"title" :"test",
"body" : "hellooooo",
},
"badge" : 1,
"sound" : "default",
"content_available" : 1,
},
"person"
{
"userIdTo": 12,
"ListID" : 0,
}
}
I was trying to update the package to the latest version, but received this error: "Could not install package 'CorePush 2.1.1'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.7.2', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author."
Could you please help? Thank you.
As .NET Standard 2.1 currently removes support for .NET Framework completely.
https://devblogs.microsoft.com/dotnet/announcing-net-standard-2-1/
States:
In fact, most libraries should be able to stay on .NET Standard 2.0, as the API additions are largely for advanced scenarios
Hi,
We are not able to send notifications via Apn with version 3.1.1 and 3.1.0 (older ones work!). ApnSender fails with:
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at CorePush.Utils.JsonHelper.Deserialize[TObject](String json)
at CorePush.Apple.ApnSender.SendAsync(Object notification, String deviceToken, String apnsId, Int32 apnsExpiration, Int32 apnsPriority, Boolean isBackground, CancellationToken cancellationToken)
Thanks!
Hello!
I've tried to send the push through the lib and got the 200 status without any errors using the next sample code:
var settings = new ApnSettings
{
P8PrivateKey = "XXX",
P8PrivateKeyId = "XXX",
AppBundleIdentifier = "com.XXX.XXX",
ServerType = ApnServerType.Development,
TeamId = "XXX"
};
var apn = new ApnSender(settings, new HttpClient() {DefaultRequestVersion = new Version(2, 0) });
var notification = new AppleNotification() { Payload = new AppleNotification.ApsPayload { AlertBody = "Server" } };
var res = await apn.SendAsync(notification, id);
Here is my AppleNotification class:
public class AppleNotification{
public ApsPayload Payload { get; set; }
public class ApsPayload
{
[JsonProperty("alert")]
public string AlertBody { get; set; }
}
}
Could you please assist me with this issue? Might it be due to the usage of MacOs?
Thanks in advance!
Can use p12 instead of p8 in net-core-push-notifications?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.