Push sharp - APNS Notifications not being sent - c#

I'm currently developing an app with Telerik, and I need push notifications, I have set this up using Push Sharp in my api, gcm notifications are sending correctly to android phones, but when I run sendToiOS, iPhones do not receive APNS notifications.
I have checked using break points and can see that OnNotificationSucceeded is being called, and OnNotificationFailed is not. Which would be a good sign, however the Notifications don't seem to be coming through, I think I may have something wrong with the configuration of the APNSServiceBroker. Please note that "AppleCert" is a byte array containing the .p12 certificate for the app.
private static void sendToiOS(string deviceRegId, object notificationToSend, FERIS.Data.Model.Notification notification)
{
string json = JsonConvert.SerializeObject(notificationToSend);
Apns.QueueNotification(new ApnsNotification
{
DeviceToken = deviceRegId,
Payload = JObject.Parse(json)
});
}
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production,AppleCert,"IFB_4222");
Apns = new ApnsServiceBroker(config);
Apns.OnNotificationFailed += (NotificationFailed, aggregateEx) => {
aggregateEx.Handle(ex => {
return true;
});
};
Apns.OnNotificationSucceeded += (NotificationSent) => {
Console.WriteLine("Notification Sent!");
sentTotal++;
};

Related

Firebase: server response does not contain a JSON object

I am trying to run a ASP.NET Core API to send FCM push notifications.
The API works with Firebase SDK. The code is basically the one in the documentation:
Initialize the default app, configPath being the JSON project configuration
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.FromFile(configPath), //JSON con API Key credentials
});
Example of the payload I am sending
//Send a message to the device corresponding to the provided
//registration token.
//var message = new Message()
//{
// Data = new Dictionary<string, string>()
// {
// { "score", "850" },
// { "time", "2:45" },
// },
// Token = registrationToken,
// Notification = new Notification
// {
// Body = "Test"
// }
//};
The async task I am sending
string response = await FirebaseMessaging.DefaultInstance.SendAsync(payload).ConfigureAwait(false);
Everything works OK on local (push notifications are being send), configuration seems to be alright but the deployed API running on my server returns the following error:
Server runs on Windows 10, has internet connectivity and already has other APIs (not FCM related) working fine.
As a ServiceUnavailable error I have already checked if its a Firebase problem but then again if it is Firebase problem it wouldn't work on local, right?

Send notification from C# to web Cause Error Auth error from APNS or Web Push Service

I am trying to send notification to my web app using Firebase. I successfully followed the steps mentioned here to setup a JavaScript Firebase Cloud Messaging client app. Then successfully I got user approval and subscription token. Here is the code
subscribeToNotifications() {
const messaging = firebase.messaging();
messaging.requestPermission().then(function () {
console.log('have permission');
return messaging.getToken();
})
.then(function(token){
console.warn('Messaging Token: ' + token)
})
.catch(function (err) {
console.error(err);
})
}
Then I am trying to use this token to send notification from my C# console. So, here is what I did so far:
First: I generated a private key file for my service account following these steps
In the Firebase console, open Settings > Service Accounts.
Click Generate New Private Key, then confirm by clicking Generate Key.
Securely store the JSON file containing the key.
Second: I created a .net core C# console app and did the following to initialize firebase.
Installed the firebase admin package
Install-Package FirebaseAdmin -Version 1.8.0
Wrote the following code to initialize the firebase app
static void Main(string[] args)
{
FirebaseApp.Create(new AppOptions()
{
Credential =
GoogleCredential.FromFile("D:\\__\\myprojectcred.json"),
});
Console.WriteLine("Initialized");
SendMessageAsync().Wait();
}
The application successfully initialized.
However, when I tried to send the message by calling SendMessageAsync it fails in this line
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
The code is as follow:
public static async System.Threading.Tasks.Task SendMessageAsync()
{
// This registration token comes from the client FCM SDKs.
var registrationToken = "eRXeB4adi0k:APA91HGlcqh8Ow…nlrO8";
// See documentation on defining a message payload.
var message = new Message()
{
Data = new Dictionary<string, string>()
{
{ "score", "850" },
{ "time", "2:45" },
},
Token = registrationToken,
};
// Send a message to the device corresponding to the provided
// registration token.
string response = await FirebaseMessaging.DefaultInstance.SendAsync(message);
// Response is a message ID string.
Console.WriteLine("Successfully sent message: " + response);
}
The error is
FirebaseMessagingException: Auth error from APNS or Web Push Service
Please help to figure out the problem.
Update:
The notification is sent to the server successfully when I tested it with Firefox client, so now the problem is with Edge browser only.

HttpClient missing last byte in response.content

I have a Xamarin.Forms App which should communicate with an embedded device via a RESTService.
So in my SharedProject I have a Service which wraps a httpclient.
HttpClient client = new HttpClient() { Timeout = new TimeSpan(0, 0, 31) };
public async Task<MetaData> RequesMetaData()
{
try
{
var response =await client.GetAsync("http://192.168.1.23:9090/api/meta/", HttpCompletionOption.ResponseContentRead);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
var meta = JsonConvert.DeserializeObject<MetaData>(result);
return meta;
}
catch(OperationCanceledException ocex)
{
ConnectionError?.Invoke(new Message { MessageInfo = ocex.Message, IsError = true });
return new MetaData();
}
catch(Exception ex)
{
ConnectionError?.Invoke(new Message { MessageInfo = ex.Message, IsError = true });
Debug.Print(ex.GetType().Name);
return new MetaData();
}
}
The call should return a Json, which works most times.
The problem is sometimes, the last byte, the curly bracket '}' of the Json is missing.
It is always the last '}', no matter how long the message sent by the server was.
This only occurs on Android. When I test the RESTservice from Firefox,
no such error occurs. Additionally I logged with Wireshark, which reports the full json was delivered over the wire.
Also I tried the same code in a WPF Desktop App, which works flawless. Only on Xamarin Android it is missing the last byte. In the Android Options,
I tried all options (Android,Managed,Default).
Instead of ReadAsStringAsync(), I also tried ReasAsStreamAsync(), but got the same results.
When changing to https, this issue persits but in another form. Instead of the missing last byte, on occassion the Content will just be an empty string "",
maybe because the message could not be decrypted.
For testing I use the x86 Emulator of VisualStudio(Android 9) , as well as a Nexus 5 (Android 6).
I think I found the issue.
The server of the embedded device I was talking to was using http/1.0 and didn't include content-length. Changing it to use http/1.1 and using content-lenght solved the issue for me.
I can only guess that Xamarin.Android HttpClient has problems with http/1.0.

I am working on Sending push notification to android devices from C# Web app

I am Creating Application to send push notifications to Android devices using firebase and azure notification hub.
How to store RegistrationID using Push.RegisterAsync In my Code ...
Here RegistrationId is generated from firebaseinstanceID Refresh Token which is every time new So how Can I handle thatid` for sending notifications to registered devices?
var refreshedToken = FirebaseInstanceId.Instance.Token;
var templates = new JObject();
templates["genericMessage"] = new JObject
{
{ "body", templateBodyFCM }
};
var client = new MobileServiceClient(HalalApps.App.MobileServiceUrl);
var push = client.GetPush();
await push.RegisterAsync(refreshedToken, templates);

Push notifications on Xamarin IOS

we're developing a cross platform(ios and android) app on Xamarin using Xamarin.Forms. We've managed to get the same application working on IOS and Android. Great!
We would like to include push notifications in our app and this already works in Android. For IOS however, it's a completely different story.. No bare bones library to be found, Anywhere!!
For android we used the Google Cloud Messaging Client by Redth, this libary is so easy to use. We had it running in 2 hours or less. However, Nothing to be found anything like this for IOS.
How do i register my IOS device for push notifications in xamarin? We already have the right certificates, etc. its only the device side we need to get working. Something to point me in the right direction?
Use this push notification link for getting or enabling push notification services in IOS.
You will need to do following steps:
1> Create and download SSL and APNS certificates and push notification enabled provisioning profile.
2> First double click on SSL certificates than APNS certificates than provisioning profile.
3.> Now export p12 file from key-chain access and create PEM file from command prompt.
4> Now Register for push notification within FinishedLaunching.
5.> Run your program , You will get a device token and send it to the server.
Now APNS server would send this notification respective to the token.
You might want to look into PushSharp to power the server side part of the iOS and Android notifications. I believe they also have a Xamarin.iOS library you can use to subscribe to the push notifications.
// Register for push notifications.
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
{
var authOptions = UserNotifications.UNAuthorizationOptions.Alert | UserNotifications.UNAuthorizationOptions.Badge | UserNotifications.UNAuthorizationOptions.Sound;
UserNotifications.UNUserNotificationCenter.Current.RequestAuthorization(authOptions, (granted, error) =>
{
Console.WriteLine(granted);
});
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound, new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
var notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}
}
private SBNotificationHub Hub { get; set; }
public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);
//if user is not logged In
Employee employee = JsonConvert.DeserializeObject<Employee>(Settings.CurrentUser);
if (employee != null)
{
NSSet tags = new NSSet(new string[] { "username:" + employee.Email }); // create tags if you want
Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) =>
{
if (errorCallback != null)
Console.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
});
}
else
{
Hub.UnregisterAllAsync(deviceToken, (error) =>
{
if (error != null)
{
Console.WriteLine("Error calling Unregister: {0}", error.ToString());
return;
}
});
}
}
public override void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
{
AzurePushNotificationManager.RemoteNotificationRegistrationFailed(error);
}
public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
{
ProcessNotification(userInfo, false);
}
void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
{
// Check to see if the dictionary has the aps key. This is the notification payload you would have sent
if (null != options && options.ContainsKey(new NSString("aps")))
{
//Get the aps dictionary
NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
string alert = string.Empty;
if (aps.ContainsKey(new NSString("alert")))
alert = (aps[new NSString("alert")] as NSString).ToString();
if (!fromFinishedLaunching)
{
//Manually show an alert
if (!string.IsNullOrEmpty(alert))
{
NSString alertKey = new NSString("alert");
UILocalNotification notification = new UILocalNotification();
notification.FireDate = NSDate.Now;
notification.AlertBody = aps.ObjectForKey(alertKey) as NSString;
notification.TimeZone = NSTimeZone.DefaultTimeZone;
notification.SoundName = UILocalNotification.DefaultSoundName;
UIApplication.SharedApplication.ScheduleLocalNotification(notification);
}
}
}
}

Categories