Hi I am working on web api as back-end service where I am using Azure notification hub. I need to notify logged in user according to conditional business logic, in short target
Here is complete working implementation. Modify according to your need
public class MyAzureNotificationHubManager
{
private Microsoft.ServiceBus.Notifications.NotificationHubClient _hub;
public MyAzureNotificationHubManager()
{
_hub = MyAzureNotificationClient.Instance.Hub;
}
private const string TAGFORMAT = "username:{0}";
public async Task<string> GetRegistrationIdAsync(string handle)
{
if (string.IsNullOrEmpty(handle))
throw new ArgumentNullException("handle could not be empty or null");
// This is requied - to make uniform handle format, otherwise could have some issue.
handle = handle.ToUpper();
string newRegistrationId = null;
// make sure there are no existing registrations for this push handle (used for iOS and Android)
var registrations = await _hub.GetRegistrationsByChannelAsync(handle, 100);
foreach (RegistrationDescription registration in registrations)
{
if (newRegistrationId == null)
{
newRegistrationId = registration.RegistrationId;
}
else
{
await _hub.DeleteRegistrationAsync(registration);
}
}
if (newRegistrationId == null)
newRegistrationId = await _hub.CreateRegistrationIdAsync();
return newRegistrationId;
}
public async Task UnRegisterDeviceAsync(string handle)
{
if (string.IsNullOrEmpty(handle))
throw new ArgumentNullException("handle could not be empty or null");
// This is requied - to make uniform handle format, otherwise could have some issue.
handle = handle.ToUpper();
// remove all registration by that handle
var registrations = await _hub.GetRegistrationsByChannelAsync(handle, 100);
foreach (RegistrationDescription registration in registrations)
{
await _hub.DeleteRegistrationAsync(registration);
}
}
public async Task RegisterDeviceAsync(string userName, string registrationId, Platforms platform, string handle)
{
if (string.IsNullOrEmpty(handle))
throw new ArgumentNullException("handle could not be empty or null");
// This is requied - to make uniform handle format, otherwise could have some issue.
handle = handle.ToUpper();
RegistrationDescription registration = null;
switch (platform)
{
case Platforms.MPNS:
registration = new MpnsRegistrationDescription(handle);
break;
case Platforms.WNS:
registration = new WindowsRegistrationDescription(handle);
break;
case Platforms.APNS:
registration = new AppleRegistrationDescription(handle);
break;
case Platforms.GCM:
registration = new GcmRegistrationDescription(handle);
break;
default:
throw new ArgumentException("Invalid device platform. It should be one of 'mpns', 'wns', 'apns' or 'gcm'");
}
registration.RegistrationId = registrationId;
// add check if user is allowed to add these tags
registration.Tags = new HashSet<string>();
registration.Tags.Add(string.Format(TAGFORMAT, userName));
// collect final registration
var result = await _hub.CreateOrUpdateRegistrationAsync(registration);
var output = new RegistrationOutput()
{
Platform = platform,
Handle = handle,
ExpirationTime = result.ExpirationTime,
RegistrationId = result.RegistrationId
};
if (result.Tags != null)
{
output.Tags = result.Tags.ToList();
}
}
public async Task<bool> Send(Platforms platform, string receiverUserName, INotificationMessage message)
{
string[] tags = new[] { string.Format(TAGFORMAT, receiverUserName) };
NotificationOutcome outcome = null;
switch (platform)
{
// Windows 8.1 / Windows Phone 8.1
case Platforms.WNS:
outcome = await _hub.SendWindowsNativeNotificationAsync(message.GetWindowsMessage(), tags);
break;
case Platforms.APNS:
outcome = await _hub.SendAppleNativeNotificationAsync(message.GetAppleMessage(), tags);
break;
case Platforms.GCM:
outcome = await _hub.SendGcmNativeNotificationAsync(message.GetAndroidMessage(), tags);
break;
}
if (outcome != null)
{
if (!((outcome.State == NotificationOutcomeState.Abandoned) || (outcome.State == NotificationOutcomeState.Unknown)))
{
return true;
}
}
return false;
}
}
public class MyAzureNotificationClient
{
// Lock synchronization object
private static object syncLock = new object();
private static MyAzureNotificationClient _instance { get; set; }
// Singleton inistance
public static MyAzureNotificationClient Instance
{
get
{
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new MyAzureNotificationClient();
}
}
}
return _instance;
}
}
public NotificationHubClient Hub { get; private set; }
private MyAzureNotificationClient()
{
Hub = Microsoft.ServiceBus.Notifications.NotificationHubClient.CreateClientFromConnectionString("<full access notification connection string>", "<notification hub name>");
}
}
public interface INotificationMessage
{
string GetAppleMessage();
string GetAndroidMessage();
string GetWindowsMessage();
}
public class SampleMessage : INotificationMessage
{
public string Message { get; set; }
public string GetAndroidMessage()
{
var notif = JsonObject.Create()
.AddProperty("data", data =>
{
data.AddProperty("message", this.Message);
});
return notif.ToJson();
}
public string GetAppleMessage()
{
// Refer - https://github.com/paultyng/FluentJson.NET
var alert = JsonObject.Create()
.AddProperty("aps", aps =>
{
aps.AddProperty("alert", this.Message ?? "Your information");
});
return alert.ToJson();
}
public string GetWindowsMessage()
{
// Refer - http://improve.dk/xmldocument-fluent-interface/
var msg = new XmlObject()
.XmlDeclaration()
.Node("toast").Within()
.Node("visual").Within()
.Node("binding").Attribute("template", "ToastText01").Within()
.Node("text").InnerText("Message here");
return msg.GetOuterXml();
}
}
Just after submitting this question I tried updating tags from VS notification explorer. There I found that tags does not allowed blank spaces and my tags format in api call has spaces. These spaces are the main culprit. API call silently ignore these invalid tag formats