IOS Push Notification doesn't work using PushSharp - c#

Im using PushSHarp on my project via Nuget and VisualStudio (c#) to try to send push notification through APN.
I created all of the file that required using my Apple account(development certificate, .p12 files etc).
Each time i used the right code i stil have the same error( i recreated all of the thing to be sure my token id is not bad):
ID= 1 Code= ConnectionError
PushSharp.Common.NotificationException: Invalid DeviceToken à
PushSharp.Apple.ApnsNotification.ToBytes() à
PushSharp.Apple.ApnsConnection.createBatch(List1 toSend) à
PushSharp.Apple.ApnsConnection.<SendBatch>d__21.MoveNext() Message
Apns notification error: 'ConnectionError' String
PushSharp.Apple.ApnsNotificationException: Apns notification error:
'ConnectionError' ---> PushSharp.Common.NotificationException: Invalid
DeviceToken à PushSharp.Apple.ApnsNotification.ToBytes() à
PushSharp.Apple.ApnsConnection.createBatch(List1 toSend) à
PushSharp.Apple.ApnsConnection.d__21.MoveNext()
Can you help me in this issue please? i really dont understand what happened.
I am using the below code given in their git wiki page to send the notifications here is the code
string TokenId = "f38205ce2137862735bd32e85b581dc85e2dc0abc04a2702e2899bddb9114543";
PushNotificationApple _notifservice = new PushNotificationApple();
_notifservice.SendAppleNotification(TokenId, "Test1");
public void SendAppleNotification(string tokenId, string message)
{
byte[] appleCert = null;
try
{
appleCert = File.ReadAllBytes("F:\\Dev\\ap.p12");
System.Diagnostics.Debug.WriteLine("OK LECTURE APPLE CERT");
}
catch (Exception ex)
{
var toto = ex.Message;
System.Diagnostics.Debug.WriteLine(" Exception lecture"+ ex.Message);
}
// Configuration (NOTE: .pfx can also be used here)
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox, appleCert, "BrumbySolution99");
// Create a new broker
var apnsBroker = new ApnsServiceBroker(config);
// Wire up events
apnsBroker.OnNotificationFailed += (notification, aggregateEx) =>
{
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
System.Diagnostics.Debug.WriteLine("ERRREUR NOTIFICATION");
var notificationException = (ApnsNotificationException)ex;
// Deal with the failed notification
var apnsNotification = notificationException.Notification;
var statusCode = notificationException.ErrorStatusCode;
System.Diagnostics.Debug.WriteLine("Apple Notification Failed: ID= " + notificationException.Notification.Identifier+" Code= "+ statusCode);
System.Diagnostics.Debug.WriteLine("link "+ ex.HelpLink);
System.Diagnostics.Debug.WriteLine("Inner "+ ex.InnerException);
System.Diagnostics.Debug.WriteLine("Message " + ex.Message);
System.Diagnostics.Debug.WriteLine("String " + ex.ToString());
}
else
{
// Inner exception might hold more useful information like an ApnsConnectionException
System.Diagnostics.Debug.WriteLine("Apple Notification Failed for some unknown reason : {ex.InnerException}");
}
// Mark it as handled
return true;
});
};
apnsBroker.OnNotificationSucceeded += (notification) =>
{
System.Diagnostics.Debug.WriteLine("APPLE NOTIFICATION SENT");
// Console.WriteLine("Apple Notification Sent!");
};
// Start the broker
apnsBroker.Start();
var notification_message = "{\"aps\":{\"alert\":{\"title\":\" Title " + message + "\",\"body\":\"Body " + message + "\"},\"badge\":\"1\"}}";
// Queue a notification to send
apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = tokenId,
Payload = JObject.Parse(notification_message)
});
// Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
apnsBroker.Stop();
}
}

Related

How to get the hub notification that is not full?

I have a notification hub, and it, have a hub-namespace and it is almost full.
I'll create another hub, how do I programmatically know (Android), which one should I enter the user?
Android source code:
public class NotificationSettings {
public static String SenderId = "MyFirebaseSenderId";
public static String HubName = "myhub-hub";
public static String HubListenConnectionString = "Endpoint=sb://myapp.serv.../;SharedAccessKeyName=D..ure;SharedAccessKey=K..t/n8I/X..=";
}
RegistrationIntent:
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private NotificationHub hub;
public RegistrationIntentService() {
super(TAG);
}
public ApplicationUtils getApplicationUtils() {
return (ApplicationUtils) getApplication();
}
#Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String resultString = null;
String regID = null;
String storedToken = null;
String tag = null;
try {
tag ="_UserId:" + getApplicationUtils().getUsuario().Id;
} catch (Exception e){
return;
}
try {
if(FirebaseInstanceId.getInstance() == null){
FirebaseApp.initializeApp(this);
}
String FCM_token = FirebaseInstanceId.getInstance().getToken();
SaveSharedPreferences.setFCM(getApplicationContext(),FCM_token);
Log.d(TAG, "FCM Registration Token: " + FCM_token);
// Storing the registration id that indicates whether the generated token has been
// sent to your server. If it is not stored, send the token to your server,
// otherwise your server should have already received the token.
if (((regID=sharedPreferences.getString("registrationID", null)) == null)){
NotificationHub hub = new NotificationHub(NotificationSettings.HubName,
NotificationSettings.HubListenConnectionString, this);
Log.d(TAG, "Attempting a new registration with NH using FCM token : " + FCM_token);
regID = hub.register(FCM_token, tag).getRegistrationId();
// If you want to use tags...
// Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/
// regID = hub.register(token, "tag1,tag2").getRegistrationId();
resultString = "New NH Registration Successfully - RegId : " + regID;
Log.d(TAG, resultString);
sharedPreferences.edit().putString("registrationID", regID ).apply();
sharedPreferences.edit().putString("FCMtoken", FCM_token ).apply();
}
// Check if the token may have been compromised and needs refreshing.
else if (!((storedToken=sharedPreferences.getString("FCMtoken", "")).equals(FCM_token))) {
NotificationHub hub = new NotificationHub(NotificationSettings.HubName,
NotificationSettings.HubListenConnectionString, this);
Log.d(TAG, "NH Registration refreshing with token : " + FCM_token);
regID = hub.register(FCM_token, tag).getRegistrationId();
// If you want to use tags...
// Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/
// regID = hub.register(token, "tag1,tag2").getRegistrationId();
resultString = "New NH Registration Successfully - RegId : " + regID;
Log.d(TAG, resultString);
sharedPreferences.edit().putString("registrationID", regID ).apply();
sharedPreferences.edit().putString("FCMtoken", FCM_token ).apply();
}
else {
resultString = "Previously Registered Successfully - RegId : " + regID;
}
} .............................................
Now, it follows my downend code below, I do not know if it would be important in this case. But, it is developed in C # .Net:
public static async void sendPushNotification(ApiController controller, DataObjects.Notification notification)
{
// Get the settings for the server project.
HttpConfiguration config = controller.Configuration;
MobileAppSettingsDictionary settings =
controller.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
// Get the Notification Hubs credentials for the Mobile App.
string notificationHubName = settings.NotificationHubName;
string notificationHubConnection = settings
.Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
// Create a new Notification Hub client.
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
// Android payload
JObject data = new JObject();
data.Add("Id", notification.Id);
data.Add("Descricao", notification.Descricao);
...
//alteração com a colocação da tag priority em caso de erro teste sem
var androidNotificationPayload = "{ \"data\" : {\"message\":" + JsonConvert.SerializeObject(data) + "}}";
try
{
// Send the push notification and log the results.
String tag = "_UserId:"+notification.Id_usuario;
//var result = await hub.SendGcmNativeNotificationAsync(androidNotificationPayload);
var result = await hub.SendGcmNativeNotificationAsync(androidNotificationPayload, tag);
// Write the success result to the logs.
config.Services.GetTraceWriter().Info(result.State.ToString());
}
catch (System.Exception ex)
{
// Write the failure result to the logs.
config.Services.GetTraceWriter().Error(ex.Message, null, "Push.SendAsync Error");
}
}
I need a lot of help on this issue.
Thank you so much for this.
According to your description, I suggest you could write a api method which will insert new user to the notification hub(not on the client side) after checking the registrations is full or not.
We could use NotificationHubClient.GetAllRegistrationsAsync Method to get all AllRegistrations to local. Then we could count its number.
After checking successfully, then we will check enter user to which hub.
The workflow is:
New user registered:
Client: Send the user information to server web api method
Server: Check the notification hub is full(By calling NotificationHubClient.GetAllRegistrationsAsync or directly registered user if it failed registered into new hub)
Besides, notification hub provides different pricing tier.
I suggest you could consider scaling up your pricing tier to support multiple active devices.

How can I use User Agent to detect request is Coming from desktop or mobile?

Here Is My method where I am getting userdetails who logging my application.I want to check the request is coming from desktop or mobile,using User agent.How can I do this?
public UserDetails Authenticate()
{
try
{
_logger.Info("authenticating...");
var message = OperationContext.Current.RequestContext.RequestMessage;
var request = (HttpRequestMessageProperty)message.Properties[HttpRequestMessageProperty.Name];
string token = request.Headers[HttpRequestHeader.Authorization];
var base64decodedtoken = this.Base64Decode(token);
UserBLL user = new UserBLL();
var userdetails = user.GetUserDetails(base64decodedtoken, true);
if (userdetails.UserId > 0)
{
_logger.Info("authentication successfull... for user id" + userdetails.UserId);
int i = user.AuditUserLogin(userdetails.Email);
}
else
{
_logger.Info("Unauthorised Access" + userdetails.Email);
}
return userdetails;
}
catch (Exception ex)
{
_logger.Error("Error Occured in Authentication Service", ex);
ErrorData errorData = new ErrorData("Error Occured ", ex.Message);
throw new WebFaultException<ErrorData>(errorData, HttpStatusCode.Unauthorized);
}
}
Please refer to this MDN article for your answer.
Basically, the mobile/desktop detection by user-agent is not suggested, but if you have to get your work sorted in this way, you can also refer to this link

Azure Notification Hubs with Android - Sending notifications to subsets of users

I am currently building an Android messaging app and I am trying to send notifications to all users who are part of a group. I have an Azure Notification Hub set up which is working fine for sending a notification to all devices that are registered, but I cannot seem to get it working for just a subset of all user ie a group.
The devices register with Azure and with GCM on startup.
I have tried using "Tags" to try send a notification to an individual but I am not sure if I am doing it right... I must not be because it isn't working!
In the following code I am trying to send a notification to an individual by using their username as a Tag...
This is the code in my service to send a notification:
// POST api/notification
public async Task<IHttpActionResult> Post([FromBody]Notification notification)
{
var notificationToSave = new Notification
{
NotificationGuid = Guid.NewGuid().ToString(),
TimeStamp = DateTime.UtcNow,
Message = notification.Message,
SenderName = notification.SenderName
};
var recipientNames = await GetRecipientNamesFromNotificationHub();
var recipientNamesString = CreateCustomRecipientNamesString(recipientNames);
string notificationJsonPayload =
"{\"data\" : " +
" {" +
" \"message\": \"" + notificationToSave.Message + "\"," +
" \"senderName\": \"" + notificationToSave.SenderName + "\"," +
" \"recipientNames\": \"" + recipientNamesString + "\"" +
" }" +
"}";
var result = await _hubClient.SendGcmNativeNotificationAsync(notificationJsonPayload, "ken#test.com"); // If this second parameter is omitted then a notification is sent to all registered devices.
notificationToSave.TrackingId = result.TrackingId;
notificationToSave.Recipients = recipientNames;
await Session.StoreAsync(notificationToSave);
return Ok(notificationToSave);
}
And this is how I am registering a device on the Android side:
private void sendRegistrationIdToBackend(String registrationId) {
String backendBaseUrl = "http://myurl.net/";
if (backendBaseUrl == null || backendBaseUrl == "")
{
return;
}
PushNotificationClient client = new PushNotificationClient(backendBaseUrl);
Device device = createDevice(registrationId);
client.registerDevice(device, new Callback<Device>() {
#Override
public void success(Device device, Response response) {
//writeStringToSharedPreferences(SettingsActivity.SETTINGS_KEY_DEVICEGUID, device.DeviceGuid);
Toast.makeText(context, "Device successfully registered with backend, DeviceGUID=" + device.DeviceGuid, Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError retrofitError) {
Toast.makeText(context, "Backend registration error:" + retrofitError.getMessage(), Toast.LENGTH_LONG).show();
}
});
Log.i(TAG, registrationId);
}
private Device createDevice(String registrationId) {
Device device = new Device();
device.Platform = "Android";
device.Token = registrationId;
device.UserName = LogInActivity.loggedInUser;
device.DeviceGuid = null;
//todo set device.PlatformDescription based on Android version
device.SubscriptionCategories = new ArrayList<>();
device.SubscriptionCategories.add("ken#test.com"); // This should be adding this username as a Tag which is referenced in the service.... Not sure if this is how I should do it!
return device;
}
This is how I registering a device:
private async Task<RegistrationDescription> RegisterDeviceWithNotificationHub(Device device)
{
var hubTags = new HashSet<string>()
.Add("user", new[] { device.UserName })
.Add("category", device.SubscriptionCategories);
var hubRegistrationId = device.HubRegistrationId ?? "0";//null or empty string as query input throws exception
var hubRegistration = await _hubClient.GetRegistrationAsync<RegistrationDescription>(hubRegistrationId);
if (hubRegistration != null)
{
hubRegistration.Tags = hubTags;
await _hubClient.UpdateRegistrationAsync(hubRegistration);
}
else
{
hubRegistration = await _hubClient.CreateGcmNativeRegistrationAsync(device.Token, hubTags);
}
return hubRegistration;
}
good evening.
You should try check your registrations by using Visual studio 2015.
Install it, connect azure, azure hubs, registred devices. And try send your test message on test token (+check "does your registration exist on notification hub").

Getting Command Not Valid Error logging into Exchange Server using POP 3

I have an application that monitors an Exchange Server mailbox for incoming mail. It works on other systems, but for one of our customers we are getting an error: -ERR Command is not valid in this state.
I don't think it has anything to do with the code itself because we get the same error message when we try logging in using Telnet. The error comes when the User is passed. Just for reference, I have added my login code below.
try
{
tcpClient = new TcpClient(Host, Port);
}
catch (SocketException e) { ... }
String response = "";
try
{
streamReader = GetStreamReader(tcpClient);
response = streamReader.ReadLine();
if (response.StartsWith("+OK"))
{
response = SendReceive("USER ", UserName.Trim() + "#" + Domain.Trim());
if (response.StartsWith("+OK"))
response = SendReceive("PASS ", Password);
}
}
catch (Exception e) { ... }
And the SendReceive method is below:
private String SendReceive(String command, String parameter)
{
String result = null;
try
{
String myCommand = command.ToUpper().Trim() + " " + parameter.Trim() + Environment.NewLine;
byte[] data = System.Text.Encoding.ASCII.GetBytes(myCommand.ToCharArray());
tcpClient.GetStream().Write(data, 0, data.Length);
result = streamReader.ReadLine();
}
catch { } // Not logged in...
return result;
}
Some POP3 servers do not allow the USER command to be used until/unless the connection is using SSL.
In other words, you may need to use the STLS command first (if it is supported), or, failing that, you may be required to use a SASL authentication mechanism.
Check the results of the CAPA command for more information.
Oh, and shameless plug: use MailKit instead of trying to roll your own.

Using .net PUT to IBM MQ queue no longer sending message

In c#, PUT is no longer sending messages but the try catch is not throwing an error. I can not find a trace or error log on the client. Please let me know where else to look for a clue to what has changed.
The client is on a Windows 2012 server and MQ is on a mainframe.
// in class constuctor
try
{
_queueManager = new MQQueueManager(queueManagerName, channelName, connectionName);
_requestQueue = _queueManager.AccessQueue(queueName, MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING); //added | MQC.MQOO_INQUIRE
}
catch (MQException MQexp)
{
Console.WriteLine("Error:" + MQexp.Message);
Console.Read();
}
public string Queue_PutTestMsgs(string message)
{
MQMessage queueMessage = new MQMessage();
MQPutMessageOptions queuePutMessageOptions = new MQPutMessageOptions();
try
{
queueMessage.Format = MQC.MQFMT_STRING;
queueMessage.MessageType = MQC.MQMT_REQUEST;
queueMessage.ReplyToQueueManagerName = _responseQueueManagerName;//added
queueMessage.ReplyToQueueName = _responseQueueName;
queueMessage.WriteString(message);
_requestQueue.Put(queueMessage, queuePutMessageOptions);
}
catch (MQException MQexp)
{
Console.WriteLine("Error:" + MQexp.Message);
Console.Read();
}
return message;
}

Categories