I am attempting to use the PushSharp library for apple push notifications in a c# service I am running.
The code all appears to execute correctly, there are no errors and it seems all things are done correctly. However the notification never reaches my application.
Everything Ive read seems to conclude the issue is my certificate, but ive re-downloaded, and redone the steps numerous times and everything seems to be correct with it.
Here is my PushSharp c# code
string pushCertPath = string.Format(string.Format("{0}\\PushCert (DEV).p12", dataPath));
var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, pushCertPath));
PushBroker push = new PushBroker();
push.RegisterAppleService(new ApplePushChannelSettings(false, appleCert,"pushcert"));
push.QueueNotification(new AppleNotification()
.ForDeviceToken("594c78b070698ded0a5f3dc1503a42e3983b7c1d254b61a98cc6e5eb0e8b7edd")
.WithAlert("You have received new messages")
.WithSound("default")
.WithBadge(1));
I got the same problem too since from yesterday. I just tried change the SslProtocols from SslProtocols.Ssl3 to SslProtocols.Default make it works again. So Apple must change something and refuse the Ssl3 protocol.
stream.AuthenticateAsClient(settings.FeedbackHost, certificates, System.Security.Authentication.SslProtocols.**Default**, false);
Related
I want to send notifications with FCM to an iOS App. It works fine when I send it to the token, but it doesn't work when I send it to a topic. I tried subscribing the App to the topics using this:
string[] topics = { "all", "test" };
CrossFirebasePushNotification.Current.Subscribe(topics);
(This is using the Plugin.FirebasePushNotification) or using this:
string[] tokens = { e.Token };
FirebaseMessaging.DefaultInstance.SubscribeToTopicAsync(tokens, "test");
FirebaseMessaging.DefaultInstance.SubscribeToTopicAsync(tokens, "all");
(This is using FirebaseAdmin) It's both in the App.xaml.cs, the first one beeing under InitializeComponent(); and the second one beeing in OnTokenRefresh. It works fine on android, but not on iOS. Keep in mind, that e.Token is the Token. I even tried to subscribe in the AppDelegate.cs, but it didn't work there either. I think it could be because it tries to subscribe before I even said "Yes" on the device so it can send me Notifications. I'm using an iPhone SE with iOS 15.3.
Thanks for your help!
I figured it out. In the AppDelegate.cs you can override the RegisteredForRemoteNotifications and you can just subscribe there. This means, it will subscribe if the user grants the permission to send remote notifications. After that it worked perfectly.
I am trying to send a push notification to IOS device via PushSharp. For android, it works. For IOS, the call to StopAllServices() hangs forever, without calling any exception handlers.
Could the problem be that I was given a .pem certificate file, and pushsharp requires a .p12 file?
The code is the following:
var br = new PushBroker();
br.OnNotificationSent += br_OnNotificationSent;
br.OnNotificationFailed += br_OnNotificationFailed;
br.OnChannelException += br_OnChannelException;
br.OnServiceException += br_OnServiceException;
br.OnDeviceSubscriptionChanged += br_OnDeviceSubscriptionChanged;
br.OnDeviceSubscriptionExpired += br_OnDeviceSubscriptionExpired;
br.OnChannelCreated += br_OnChannelCreated;
br.OnChannelDestroyed += br_OnChannelDestroyed;
var appleCert = Resource1.ck; // this is a pem file, not a p12 file!!! could this be the problem?
var sandbox = true;
br.RegisterAppleService(new ApplePushChannelSettings(!sandbox, appleCert, "223684"));
// password given to me by ios developer
var deviceIds = new string[] { "09eddcb8b89494adf802a0caf97d5daaa789a53f52d8c544dbdcf39f2c0b619a" };
foreach (var did in deviceIds)
{
br.QueueNotification(
new AppleNotification()
.ForDeviceToken(did)//the recipient device id
.WithAlert("test: " + DateTime.Now.ToString())//the message
.WithBadge(1)
.WithSound("sound.caf"));
}
br.StopAllServices(waitForQueuesToFinish: true); // hangs forever, no callbacks are called
I am using PushSharp taken via Git, and compiled by myself with Visual Studio 2013, as of yesterday.
The hang happens both if the code is in a console application and in an asp.net application.
I am using the sandbox, because I was told to. If I use the production server, I get an exception telling me that the certificate is for the sandbox.
Thanks for any hint as to the cause of the freeze.
We spent a whole day trying to guess the problem!
In the end it was in the wrong Newtonsoft.Json version
Some of the projects in our solution were dependant on the older version of this library as a result we had bad luck to get wrong version in the /bin folder of the Web project.
You can wait few seconds for br_OnNotificationFailed or any other event probably. It should contain some error description.
Nevertheless, I've found out PushSharp has strict requirements about certificates usage. PEM should be OK but it is not enough, even if you import it from file - you should have all necessary certificates in Windows certificates store (pem itself and its dependecies):
Import your PEM to Local Machine\Root storage and give read access rights of its private key to the user of your running application
Import from Apple site certificates Apple Worldwide Developer Relations Certification Authority and Apple Root CA into Local Machine\Trusted Root Certification Authorities
Import Entrust Secure CA certificate (for SSL as described in iOS Developer Library) into Local Machine\Trusted Root Certification Authorities
In the end it was a certificate problem. The .pem I was given is not accepted by PushSharp. Only when I was given a .p12 created with this guide
https://code.google.com/p/apns-sharp/wiki/HowToCreatePKCS12Certificate
, the problem was solved.
However, PushSharp should have raised an exception instead of hanging.
An ASP.NET application is NOT the ideal place to use PushSharp. You'd be better off using a Windows Service, or some other infrastructure if at all possible. The reason is that in an ASP.NET application, the Application Pool (AppPool) can be restarted on you and is usually not under your direct control, which means all the Queued notifications that PushSharp may be in the process of sending could be lost if PushSharp is not cleaned up gracefully.
If you MUST run PushSharp in an ASP.NET application, the best way is to create a singleton PushBroker instance in your Global.asax file. You should keep this singleton instance around for the lifespan of your web application, including a call to pushBroker.StopAllServices() when your Application is ending (Application_End in global.asax).
You can help mitigate losing messages due to unforeseen App Pool terminations or restarts by persisting notifications you want to send in some other way, and only removing them from that persistent storage once the OnNotificationSent event has fired. This is still not perfect (you may risk multiple notification deliveries), but it's probably adequate for most.
You should not be creating and destroying instances of PushBroker each time you send a notification, as this uses unnecessary resources and if you're using Apple APNS, they require you to keep the connection to their servers open as long as possible when sending notifications. You should also call pushBroker.StopAllServices() in your Application_Ended event in your Global.asax. Keep in mind that PushSharp works.
Ref: https://github.com/Redth/PushSharp/issues/240
I know this has been brought up many times but couldn't find an answer for it.
I am trying to set up push notifications in my app using the below code however I am running into the channel uri null problem.
I have tried the app on 4 different devices + emulator all under the same network conditions (Work WiFi - Home WiFi - 3G) 2 of the devices are Lumia 920 both could not obtain a channel uri, while the other 2 devices an HTC 8X and a Lumia 820 can successfully obtain channel uri and register for push.
The emulator also can obtain a channel uri successfully.
On one of the Lumia 920's it managed to get a channel uri, but I uninstalled and installed the app again and since then couldn't get any channel uri.
Below are my scenarios:
1- Lumia 920 Black installed on 3G worked fine, uninstalled/reinstalled stopped working on any connection (3G - Work WiFi - Home WiFi)
2- Lumia 920 Yellow installed on 3G - Work WiFi - Home WIfi never managed to get a channel uri
3- HTC 8X on 3G - Work WiFi - Home WiFi worked great on all 3 networks
4- Lumia 820 same as HTC 8X worked great
Please note that push notifications on other apps are working fine on all 4 devices.
I'd greatly appreciate any feedback/advice for the channel null uri
Below is the code I used, it is the same code as provided by MSDN
public MainPage()
{
/// Holds the push channel that is created or found.
HttpNotificationChannel pushChannel;
// The name of our push channel.
string channelName = "ToastSampleChannel";
InitializeComponent();
// Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName);
// If the channel was not found, then create a new connection to the push service.
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
// Register for all the events before attempting to open the channel.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
pushChannel.Open();
// Bind this new channel for toast events.
pushChannel.BindToShellToast();
}
else
{
// The channel was already open, so just register for all the events.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
// Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
MessageBox.Show(String.Format("Channel Uri is {0}",
pushChannel.ChannelUri.ToString()));
}
}
I have also experienced the same issue. And it got resolved by setting my HTC windows phone with correct date and time.Once I set the date and time automatically, My hybrid application wp8 successfully registered pushplugin and received MPNS Channeluri.
The ChannelUri was null because the new phone I was developing on would not set it's date and time correctly. Once I switched the time to be set manually, then fixed it's time, date and region and then switched it back to auto, everything worked fine such as ssl certificates, windows phone update and most importantly a ChannelUri ;)
Try going into settings > "phone + SIM" and turning off the "Data connection" option this sometimes does the trick?
Have you tried changing the options in settings > data sense? There are options there that restrict background data?
Is battery saver enabled? This limits usage when battery is low etc.
Also as mentioned above, Have you checked the date and time on the device? Maybe it's caused by the auto setting of date and time. You can fix this manually then switch back to auto. It works.
Try using a local wifi connection rather than the cell phone data connection. Disabling the phones "Data connection" as per one of the comments here will achieve this result. Although I tried this and failed it lead me to noticed that my phone was not connected to our wifi router.
NOTE: In my case we have very bad cell coverage so we use a special vodafone router that redirects all our cell phone data, calls, etc thru our fixed line Internet connection. Once I bypassed the that router I received a ChannelUri. I also tried the phone/app at work which uses a different cell tower and that was fine.
I tried setting the date manually but to no effect. What ended up working for me was to actually start the phone without the SIM card, shut down, re-insert SIM and start again. This allowed me to get a ChannelUri again.
Suspect this could be related to the suggestion of TripVoltage who suggests toggling the SIM's data connection.
I'm new to windows phone development and have started working with push notifications within the emulator in visual studio 2012. We are having a strange problem where we have two apps in visual studio and when we start each one and call the following:
CurrentChannel = HttpNotificationChannel.Find("ChannelName");
if (CurrentChannel == null)
{
CurrentChannel = new HttpNotificationChannel("ChannelName");
CurrentChannel.Open();
CurrentChannel.BindToShellTile();
CurrentChannel.BindToShellToast();
}
Even though the ChannelName is different in each app the CurrentChannel.ChannelUri is the same so when we send push notifications they only go to one app.
I am sure we are missing something very obvious or misunderstanding the way this is supposed to work but any insight would be appreciated.
I supposed you didn't get the right Uri according to your piece of codes. Try to Listen on ChannelUriUpdated event to get a fresh Uri.
If you did, maybe try it on a real device, emulator is not always to be trusted enough.
And Push notification channel URi is unique for device & app combination, to be sure you made something different in these two apps. Anyway seems this couldn't be happened.
I need to push notifications to tens of thousands of iOS devices that my app installed. I'm trying to do it with PushSharp, but I'm missing some fundamental concepts here. At first I tried to actually run this in a Windows service, but couldn't get it work - getting null reference errors coming from _push.QueueNotification() call. Then I did exactly what the documented sample code did and it worked:
PushService _push = new PushService();
_push.Events.OnNotificationSendFailure += new ChannelEvents.NotificationSendFailureDelegate(Events_OnNotificationSendFailure);
_push.Events.OnNotificationSent += new ChannelEvents.NotificationSentDelegate(Events_OnNotificationSent);
var cert = File.ReadAllBytes(HttpContext.Current.Server.MapPath("..pathtokeyfile.p12"));
_push.StartApplePushService(new ApplePushChannelSettings(false, cert, "certpwd"));
AppleNotification notification = NotificationFactory.Apple()
.ForDeviceToken(deviceToken)
.WithAlert(message)
.WithSound("default")
.WithBadge(badge);
_push.QueueNotification(notification);
_push.StopAllServices(true);
Issue #1:
This works perfectly and I see the notification pop up on the iPhone. However, since it's called a Push Service, I assumed it would behave like a service - meaning, I instantiate it and call _push.StartApplePushService() within a Windows service perhaps. And I thought to actually queue up my notifications, I could do this on the front-end (admin app, let's say):
PushService push = new PushService();
AppleNotification notification = NotificationFactory.Apple()
.ForDeviceToken(deviceToken)
.WithAlert(message)
.WithSound("default")
.WithBadge(badge);
push.QueueNotification(notification);
Obviously (and like I already said), it didn't work - the last line kept throwing a null reference exception.
I'm having trouble finding any other kind of documentation that would show how to set this up in a service/client manner (and not just call everything at once). Is it possible or am I missing the point of how PushSharp should be utilized?
Issue #2:
Also, I can't seem to find a way to target many device tokens at once, without looping through them and queuing up notifications one at a time. Is that the only way or am I missing something here as well?
Thanks in advance.
#baramuse explained it all, if you wish to see a service "processor" you can browse through my solution on https://github.com/vmandic/DevUG-PushSharp where I've implemented the workflow you seek for, i.e. a win service, win processor or even a web api ad hoc processor using the same core processor.
From what I've read and how I'm using it, the 'Service' keyword may have mislead you...
It is a service in a way that you configure it once and start it.
From this point, it will wait for you to push new notifications inside its queue system and it will raise events as soon as something happens (delivery report, delivery error...). It is asynchronous and you can push (=queue) 10000 notifications and wait for the results to come back later using the event handlers.
But still it's a regular object instance you will have to create and access as a regular one. It doesn't expose any "outside listener" (http/tcp/ipc connection for example), you will have to build that.
In my project I created a small selfhosted webservice (relying on ServiceStack) that takes care about the configuration and instance lifetime while only exposing the SendNotification function.
And about the Issue #2, there indeed isn't any "batch queue" but as the queue function returns straight away (enqueue and push later) it's just a matter of a looping into your device tokens list...
public void QueueNotification(Notification notification)
{
if (this.cancelTokenSource.IsCancellationRequested)
{
Events.RaiseChannelException(new ObjectDisposedException("Service", "Service has already been signaled to stop"), this.Platform, notification);
return;
}
notification.EnqueuedTimestamp = DateTime.UtcNow;
queuedNotifications.Enqueue(notification);
}