Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Apple Push Notification service (APNs) will no longer support the legacy binary protocol as of November 2020. #923

Closed
i5kender opened this issue Oct 11, 2020 · 24 comments

Comments

@i5kender
Copy link

Hi,
I have been using this library for 2 years. Apple says that "we recommend updating to the HTTP/2-based APNs provider API as soon as possible."
Will we be able to continue sending notifications with this library?

News link : https://developer.apple.com/news/?id=11042019a

@fcsteenkamp
Copy link

This is something I also would like to know. If anyone could shed some light on this it would be greatly appreciated.

@ibrahimozgon
Copy link

ibrahimozgon commented Oct 12, 2020

Hello,
I need to know this too. The last version is 4.0.10 and we are using it. But when I check the documentation, the URL's don't match with constants in the code.
This is ApnsConfiguration class (https://github.com/Redth/PushSharp/blob/master/PushSharp.Apple/ApnsConfiguration.cs)
image
And this is the apple's documentation page: (https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns#2947606)
image

@mubaraknet
Copy link

The commit 96ff502 says "Add basic Http2 support for APNS", but in some articles found that PushSharp doesn't support Http2 API.

It will be really helpful if someone can clear out this confusion.

Thanks

@cvocvo
Copy link

cvocvo commented Oct 12, 2020

I also saw this and @Redth covered previously (here: #880) that http/2 support requires a bunch of changes/etc. and isn't coming to PushSharp.

@fcsteenkamp
Copy link

Thanks @cvocvo

I went for the azure option, so this is going to make my life so much easier in the long run.

Azure offers the capability of managing devices through their hub, or just use it as a pass through service and you manage your own devices...which fits perfectly into my use case.

@Linkrain
Copy link

Linkrain commented Oct 19, 2020

Apple changed deadline.
The deadline to upgrade to the APNs provider API has been extended to March 31, 2021.
https://developer.apple.com/news/?id=c88acm2b

And also you can do a little trick by adding ApnsHttp2Connection and other files in project, they are already in source code of PushSharp, you need to make your own PushSharp.Apple.dll
use fork of HttpTwo
https://github.com/Neio/HttpTwo
and lock http2Client, because there are problems with asynchronous

lock (sobject) { response = http2.Send(uri, HttpMethod.Post, headers, data).Result; }
Redth/HttpTwo#7

@Gal6
Copy link

Gal6 commented Oct 20, 2020

you can use dotAPNS library to push notifications using HTTP/2
https://github.com/alexalok/dotAPNS

@hussoftware
Copy link

I am using PushSharp .NetCore and worried about this deadline as the current structure is working perfectly fine for me. Any updates?

@jpreiditsch
Copy link

Apple changed deadline.
The deadline to upgrade to the APNs provider API has been extended to March 31, 2021.
https://developer.apple.com/news/?id=c88acm2b

And also you can do a little trick by adding ApnsHttp2Connection and other files in project, they are already in source code of PushSharp, you need to make your own PushSharp.Apple.dll
use fork of HttpTwo
https://github.com/Neio/HttpTwo
and lock http2Client, because there are problems with asynchronous

lock (sobject) { response = http2.Send(uri, HttpMethod.Post, headers, data).Result; }
Redth/HttpTwo#7

This solution worked well for me. Thank you.

@Softmaker
Copy link

Will PushSharp be updated to support HTTP/2-based Apple Push Notification?

@hussoftware
Copy link

Yes I hope there will be a quick update for this HTTP/2 issue soon.

@plastovicka
Copy link

plastovicka commented Jan 21, 2021

It is easy to send Apple Push Notification. You don't need any GitHub libraries or Nuget packages. I use this simple function. It only depends on API from .Net Core 3.0.

static async Task Send(string text, string deviceToken)
{
  var cert = new X509Certificate2("certificate.p12", "password", X509KeyStorageFlags.MachineKeySet);
  var req = new HttpRequestMessage(HttpMethod.Post, "https://api.push.apple.com/3/device/" + deviceToken);
  req.Version = new Version(2, 0);
  req.Headers.Add("apns-topic", cert.Subject.Substring(cert.Subject.LastIndexOf('=') + 1));
  req.Content = new StringContent("{\"aps\":{\"alert\":\"" + HttpUtility.JavaScriptStringEncode(text) + "\"}}");
  var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
  handler.ClientCertificates.Add(cert);
  var response = await new HttpClient(handler).SendAsync(req);
  string content = await response.Content.ReadAsStringAsync();
  if (!response.IsSuccessStatusCode) throw new Exception("APNS error " + response.StatusCode + ": " + content);
}

@Softmaker
Copy link

It is easy to send Apple Push Notification. You don't need any GitHub libraries or Nuget packages. I use this simple function. It only depends on API from .Net Core 3.0.

static async Task Send(string text, string deviceToken)
{
  var cert = new X509Certificate2("certificate.p12", "password", X509KeyStorageFlags.MachineKeySet);
  var req = new HttpRequestMessage(HttpMethod.Post, "https://api.push.apple.com/3/device/" + deviceToken);
  req.Version = new Version(2, 0);
  req.Headers.Add("apns-topic", cert.Subject.Substring(cert.Subject.LastIndexOf('=') + 1));
  req.Content = new StringContent("{\"aps\":{\"alert\":\"" + HttpUtility.JavaScriptStringEncode(text) + "\"}}");
  var handler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
  handler.ClientCertificates.Add(cert);
  var response = await new HttpClient(handler).SendAsync(req);
  string content = await response.Content.ReadAsStringAsync();
  if (!response.IsSuccessStatusCode) throw new Exception("APNS error " + response.StatusCode + ": " + content);
}

I created a .NET Core 3.1 library with the code above. Then I refer to the library from a .NET Framework 4.7.2 project. The problem is that I get this error:

Error CS1705 Assembly 'X' with identity 'X, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' uses 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' which has a higher version than referenced assembly 'System.Runtime' with identity 'System.Runtime, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'

In NuGet Manager for both projects, I have tried to add System.Runtime 4.3.1. Still I get the same error. How can this be fixed?

@plastovicka
Copy link

I created a .NET Core 3.1 library with the code above. Then I refer to the library from a .NET Framework 4.7.2 project.

You can't mix .NET Core and .NET Famework together within the same project. You should convert all your .NET Framework 4.7.2 project to .NET 5. If it is too much difficult for you, it's also possible to compile Send function into standalone EXE file. Then you would use method Process.Start to call it and pass on text and deviceToken as command line parameters.

@ellenkuipers
Copy link

Hi, anyone here with a working solution for Apple push using HTTP/2?
We are using .NET 4.7.2 and converting our projects to .NET core is not an option.
I tried several solutions found on the internet but nothing seems to work. The solution that "works" (copying all HTTP2 classes from https://github.com/Redth/PushSharp/blob/master/PushSharp.Apple and adding https://github.com/Neio/HttpTwo into the project) throws an exception: System.TimeoutException: The operation has timed out. at HttpTwo.Http2Client.d__19.MoveNext(). Even when setting the timeOut to 60 seconds.
I also can't figure out how to use the WinHttpHandler. It always throws exceptions.
Anyone willing to help me to replace our PushSharp implementation with a working solution using HTTP/2? Would help a lot!

@hussoftware
Copy link

This is my solution:

PushSharp 4.0.10.0: HTTP/2-based Apple Push Notification service (APNs)
https://stackoverflow.com/questions/65703015/pushsharp-4-0-10-0-http-2-based-apple-push-notification-service-apns/66317870#66317870

I removed the iOS structure of PushSharp and implemented dotAPNS. I am still using PushSharp for Google.

@ellenkuipers
Copy link

ellenkuipers commented Mar 25, 2021

Thank you @hussoftware, yes dotAPNS is perfect for core.
Unfortunately we never found a solution to implement in our existing 4.7.2 background worker (maybe there is no solution?), so we decided to create an appservice using .NET Core 3.0, purely for iOS push. Seems to be a good solution.

@hussoftware
Copy link

@ellenkuipers I built a quick helper class for myself within a day and pointed the existing PushSharp calls to this helper. You can use and improve the helper class I shared in stackoverflow or can write a better one from scratch. dotAPNS does pretty much majority of the push notifications work.

@21pg
Copy link

21pg commented Apr 30, 2021

Thank you @hussoftware, yes dotAPNS is perfect for core.
Unfortunately we never found a solution to implement in our existing 4.7.2 background worker (maybe there is no solution?), so we decided to create an appservice using .NET Core 3.0, purely for iOS push. Seems to be a good solution.

Hi can you please share some piece of code for NET Core 3.0.. As we are getting error related to SSL after uploading it on server
while working fine for local environment. I want to be sure I missed nothing from my side..

@hussoftware
Copy link

@ellenkuipers
Copy link

Thank you @hussoftware, yes dotAPNS is perfect for core.
Unfortunately we never found a solution to implement in our existing 4.7.2 background worker (maybe there is no solution?), so we decided to create an appservice using .NET Core 3.0, purely for iOS push. Seems to be a good solution.

Hi can you please share some piece of code for NET Core 3.0.. As we are getting error related to SSL after uploading it on server
while working fine for local environment. I want to be sure I missed nothing from my side..

Hi @21pg ,

I followed all instructions under "dotAPNS ASP.NET Core integration", see https://github.com/alexalok/dotAPNS
Other than that, I resolve one single IApnsService per certificate. On Send I create the X509Certificate2 (creating it once and re-using it gave problems when working with 33+ different push certifificates in our case).

SendPushAsync:
var cert = new X509Certificate2(certificateBytes, string.Empty, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); var response = await apnsService.SendPush(push, cert);

Also we had to change the HTTP version to "2.0" in the configuration settings in Azure. In protocol settings we have HTTPS Only = On and Minimum TLS Version = 1.2. Hope this will help. Good luck!

@21pg
Copy link

21pg commented May 3, 2021

Thank you @hussoftware, yes dotAPNS is perfect for core.
Unfortunately we never found a solution to implement in our existing 4.7.2 background worker (maybe there is no solution?), so we decided to create an appservice using .NET Core 3.0, purely for iOS push. Seems to be a good solution.

Hi can you please share some piece of code for NET Core 3.0.. As we are getting error related to SSL after uploading it on server
while working fine for local environment. I want to be sure I missed nothing from my side..

Hi @21pg ,

I followed all instructions under "dotAPNS ASP.NET Core integration", see https://github.com/alexalok/dotAPNS
Other than that, I resolve one single IApnsService per certificate. On Send I create the X509Certificate2 (creating it once and re-using it gave problems when working with 33+ different push certifificates in our case).

SendPushAsync:
var cert = new X509Certificate2(certificateBytes, string.Empty, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); var response = await apnsService.SendPush(push, cert);

Also we had to change the HTTP version to "2.0" in the configuration settings in Azure. In protocol settings we have HTTPS Only = On and Minimum TLS Version = 1.2. Hope this will help. Good luck!

Thanks for your reply I tried this but
For me following trick worked-
by setting Load User Profile option as True in IIS
https://stackoverflow.com/questions/9951729/x509certificate-constructor-exception/10048789#10048789

@kikaragyozov
Copy link

kikaragyozov commented Oct 8, 2022

Has anyone had any issues with a certificate that works for Production but not Development? I've generated my wallet pass certificate from apple - the one you use to create apple passes. When I send the HTTP/2 request to the production server - everything works. The moment I send it to the development one though, I get The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'NO_ERROR' (0x0).

I think the issue might be with the certificate - if it was somehow created only for a production environment.

@rkbsoftsolutions
Copy link

Hi I am getting " MissingProviderToken" error.
Can any have insight for same.

string certificatePath = HttpContext.Current.Server.MapPath("certficate.p12");
X509Certificate2 cert = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "pwd", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
var apns = ApnsClient.CreateUsingCustomHttpClient(new HttpClient(new WinHttpHandler()), cert);
var push = new ApplePush(ApplePushType.Alert).AddAlert("title", text).AddToken(deviceToken);
var response = await apns.SendAsync(push);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests