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").
Related
Hello people im new with Unity and C#.
I have this script to create/login users and post in firebase database (with email and password).
I copied it from a youtube tutorial with a little few modifications
using System.Collections;
using System.Collections.Generic;
using FullSerializer;
using Proyecto26;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Firebase.Auth;
public class PlayerScores : MonoBehaviour
{
public Text scoreText;
public InputField getScoreText;
public InputField emailText;
public InputField usernameText;
public InputField passwordText;
private System.Random random = new System.Random();
User user = new User();
private string databaseURL = "testingurl";
private string AuthKey = "testingapikey";
public static fsSerializer serializer = new fsSerializer();
public static int playerScore;
public static string playerName;
private string idToken;
public static string localId;
private string getLocalId;
private void Start()
{
playerScore = random.Next(0, 101);
scoreText.text = "Score: " + playerScore;
}
public void OnSubmit()
{
PostToDatabase();
Debug.Log("datos subidos a database");
}
public void OnGetScore()
{
GetLocalId();
}
private void UpdateScore()
{
scoreText.text = "Score: " + user.userScore;
}
private void PostToDatabase(bool emptyScore = false, string idTokenTemp = "")
{
if (idTokenTemp == "")
{
idTokenTemp = idToken;
}
User user = new User();
if (emptyScore)
{
user.userScore = 0;
}
RestClient.Put(databaseURL + "/" + localId + ".json?auth=" + idTokenTemp, user);
}
private void RetrieveFromDatabase()
{
RestClient.Get<User>(databaseURL + "/" + getLocalId + ".json?auth=" + idToken).Then(response =>
{
user = response;
UpdateScore();
});
}
public void SignUpUserButton()
{
SignUpUser(emailText.text, usernameText.text, passwordText.text);
}
public void SignInUserButton()
{
SignInUser(emailText.text, passwordText.text);
}
private void SignUpUser(string email, string username, string password)
{
string userData = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\",\"returnSecureToken\":true}";
RestClient.Post<SignResponse>("https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=" + AuthKey, userData).Then(
response =>
{
string emailVerification = "{\"requestType\":\"VERIFY_EMAIL\",\"idToken\":\"" + response.idToken + "\"}";
RestClient.Post(
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobConfirmationCode?key=" + AuthKey,
emailVerification);
localId = response.localId;
playerName = username;
PostToDatabase(true, response.idToken);
Debug.Log("SingUp Correcto");
}).Catch(error =>
{
Debug.Log("falta email/password");
Debug.Log(error);
});
}
private void SignInUser(string email, string password)
{
string userData = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\",\"returnSecureToken\":true}";
RestClient.Post<SignResponse>("https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=" + AuthKey, userData).Then(
response =>
{
string emailVerification = "{\"idToken\":\"" + response.idToken + "\"}";
RestClient.Post(
"https://www.googleapis.com/identitytoolkit/v3/relyingparty/getAccountInfo?key=" + AuthKey,
emailVerification).Then(
emailResponse =>
{
fsData emailVerificationData = fsJsonParser.Parse(emailResponse.Text);
EmailConfirmationInfo emailConfirmationInfo = new EmailConfirmationInfo();
serializer.TryDeserialize(emailVerificationData, ref emailConfirmationInfo).AssertSuccessWithoutWarnings();
if (emailConfirmationInfo.users[0].emailVerified)
{
idToken = response.idToken;
localId = response.localId;
GetUsername();
Debug.Log("Login Correcto");
SceneManager.LoadScene("SignInEdit"); //para logear correctamente solo necesita que el email y password sean correctos, el username no importa.
}
else
{
Debug.Log("You are stupid, you need to verify your email dumb");
}
});
}).Catch(error =>
{
Debug.Log(error);
});
}
private void GetUsername()
{
RestClient.Get<User>(databaseURL + "/" + localId + ".json?auth=" + idToken).Then(response =>
{
playerName = response.userName;
});
}
private void GetLocalId()
{
RestClient.Get(databaseURL + ".json?auth=" + idToken).Then(response =>
{
var username = getScoreText.text;
fsData userData = fsJsonParser.Parse(response.Text);
Dictionary<string, User> users = null;
serializer.TryDeserialize(userData, ref users);
foreach (var user in users.Values)
{
if (user.userName == username)
{
getLocalId = user.localId;
RetrieveFromDatabase();
break;
}
}
}).Catch(error =>
{
Debug.Log(error);
});
}
}
my problem is I cant save my firebase login between scenes, When I change scene I cant interact anymore with my firebase database.
I tried make a dontdestroyonload script and add a unity gameobject what is containing my PlayerScore script, but dont worked.
I readed im need to store my userid in a static variable to call it from anywhere but I dont know how because im prettly new with c# coding
Can someone give some guidance?, thanks.
PS: the script of above need another 3 script to works, where store/get some values.
If is necessary I add them.
I think that there might be some confusion here as I see a reference to the official Firebase Unity SDK mixed with raw REST calls in RestClient. I'll answer this assuming that you're ok with using the Unity SDK. This is a far simpler integration than attempting to manually use the Firebase SDK (and gets you nice benefits - such as local caching).
1) Firebase Authentication
Once Firebase Authentication is initialized, FirebaseAuth.DefaultInstance.CurrentUser will always contain your currently signed in user or null if the user is not signed in. This value is actually stored in C++ and accessed through C#, meaning that it doesn't actually know about or abide by Unity's typical object lifecycles. That means that once you've signed in a user, this value will always hold the current user without the need to persist it across scene boundaries. In fact, this value is even preserved across runs of your game (meaning that your players don't have to log in every time).
A warning about this though: CurrentUser is updated asynchronously -- that is that there is no real guarantee that CurrentUser is up to date -- so it's generally safe to register a StateChanged listener as Puf suggested from the documentation:
Firebase.Auth.FirebaseAuth auth;
Firebase.Auth.FirebaseUser user;
// Handle initialization of the necessary firebase modules:
void InitializeFirebase() {
Debug.Log("Setting up Firebase Auth");
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
// Track state changes of the auth object.
void AuthStateChanged(object sender, System.EventArgs eventArgs) {
if (auth.CurrentUser != user) {
bool signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null) {
Debug.Log("Signed out " + user.UserId);
}
user = auth.CurrentUser;
if (signedIn) {
Debug.Log("Signed in " + user.UserId);
}
}
}
void OnDestroy() {
auth.StateChanged -= AuthStateChanged;
auth = null;
}
I would highly recommend watching my tutorial on Firebase Authentication to see how I think about integrating this with a game. The link you shared is appropriate, but I'm a little curious about the various REST calls I see in your code.
If you're using the Firebase Unity SDK, email/password authentication should be as easy as:
auth.CreateUserWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("CreateUserWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
// Firebase user has been created.
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("Firebase user created successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
to create a user and
auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("SignInWithEmailAndPasswordAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
to sign them in. That is, there should be no need to use RestClient.
2) Realtime Database
Once you're authenticated, any calls to the Firebase Realtime Database SDK will automatically use the CurrentUser value (as I mentioned before - it persists on the C++ side of the SDK).
If you're hoping to use rules to secure user data such as:
{
"rules": {
"users": {
"$user_id": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($user_id)
".write": "$user_id === auth.uid"
}
}
}
}
Then writing data:
Database.DefaultInstance.GetReference($"/users/{FirebaseAuth.DefaultInstance.CurrentUser.UserId}/mySecret").SetValueAsync("flowers");
should just work.
I hope that all helps!
--Patrick
The Firebase SDK automatically persists the authentication state, and tries to restore it automatically too. You'll just need to write code to pick it up, which involves attaching a listener to the auth state.
See the first snippet in the Firebase documentation on getting the currently signed in user:
The recommended way to get the current user is by setting a listener on the Auth object:
Firebase.Auth.FirebaseAuth auth;
Firebase.Auth.FirebaseUser user;
// Handle initialization of the necessary firebase modules:
void InitializeFirebase() {
Debug.Log("Setting up Firebase Auth");
auth = Firebase.Auth.FirebaseAuth.DefaultInstance;
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
// Track state changes of the auth object.
void AuthStateChanged(object sender, System.EventArgs eventArgs) {
if (auth.CurrentUser != user) {
bool signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null) {
Debug.Log("Signed out " + user.UserId);
}
user = auth.CurrentUser;
if (signedIn) {
Debug.Log("Signed in " + user.UserId);
}
}
}
void OnDestroy() {
auth.StateChanged -= AuthStateChanged;
auth = null;
}
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();
}
}
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.
I have this line which needs to recieve a message from the discord text channel.
choice = video[int.Parse(CommandHandler.message .Content)-1].Url;
I tried a lot of things, including searching in the api but I don't have a clue.
Here is the command
[Command("join", RunMode= RunMode.Async), Summary("joins voice channel")]
public async Task joinvoice([Remainder, Summary("The text to echo")] string searchP="")
{
IVoiceChannel voicechannel = (CommandHandler.Last as IGuildUser).VoiceChannel;
if (voicechannel == null)
{
await ReplyAsync("u have to be in a channel first");
return;
}
string choice = "";
VideoSearch SearchRisolts = new VideoSearch();
if (searchP != "")
{
if (searchP.Contains("https://"))
choice = searchP;
else
{
List<VideoInformation> video = SearchRisolts.SearchQuery(searchP, 1);
await ReplyAsync("1) " + video[0].Title + "\n\n2) " + video[1].Title + "\n\n3) " + video[2].Title);
choice = video[int.Parse(CommandHandler.message .Content)-1].Url;//here i need to recive a message from the chat
}
}
if (voicechannel != Program.voicechannel)
{
Program.audioClient = await voicechannel.ConnectAsync();
Program.voicechannel = voicechannel;
}
if (Program.audioClient!=null)
await SendAsync(Program.audioClient, choice);
}
The class containing this function should derive from BaseModule<ICommandContext>
This BaseModule contains the Context, which in place contains the message you are looking for.
Context.Message.Content
IOS platform sends JSON payload in following format:
{"aps":{"alert":"Notification Hub test notification"}}
whereas Android payload format is:
{"data":{"message":"Notification Hub test notification"}}
My SendBroadcastNotification:
public void SendBroadcastNotification(string message) {
NotificationHubClient hub = NotificationHubClient
.CreateClientFromConnectionString(Constants.NotificationsHubConnectionString, "QiKStayNotificationHub",true);
var notify = "{ \"data\" : {\"message\":\"" + message + "\"}}";
var appnotify = "{ \"aps\" : {\"alert\":\"" + message + "\"}}";
var task = hub.SendGcmNativeNotificationAsync(notify);
task.Wait();
}
Since here I am sending notification to android SendGcmNativeNotificationAsync specifically I want to broadcast it to all devices.
So shall I change the payload JSON format likewise
hubClient.SendAppleNativeNotificationAsync();
hubClient.SendGcmNativeNotificationAsync(notify);
While registering device with notification hub you should maintain user's platform
switch (platform.ToLower())
{
case "apns":
notificationMessage = "{ \"aps\" : {\"alert\":\"" + message + "\"}}";
break;
case "gcm":
notificationMessage = "{ \"data\" : {\"message\":\"" + message + "\",\"display\":\"" + title + "\"}}";
break;
default:
break;
}
or you can user template message
private static async void SendTemplateNotificationAsync()
{
// Define the notification hub.
NotificationHubClient hub =
NotificationHubClient.CreateClientFromConnectionString(
"<connection string with full access>", "<hub name>");
// Sending the notification as a template notification. All template registrations that contain
// "messageParam" or "News_<local selected>" and the proper tags will receive the notifications.
// This includes APNS, GCM, WNS, and MPNS template registrations.
Dictionary<string, string> templateParams = new Dictionary<string, string>();
// Create an array of breaking news categories.
var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
var locales = new string[] { "English", "French", "Mandarin" };
foreach (var category in categories)
{
templateParams["messageParam"] = "Breaking " + category + " News!";
// Sending localized News for each tag too...
foreach( var locale in locales)
{
string key = "News_" + locale;
// Your real localized news content would go here.
templateParams[key] = "Breaking " + category + " News in " + locale + "!";
}
await hub.SendTemplateNotificationAsync(templateParams, category);
}
}