my question is the same as this one:
android device specific push notifications by using azure mobile services
But I'm using .Net backend. This is the part where I send the notification:
Dictionary<string, string> data = new Dictionary<string, string>() { { "message", "this is the message" } };
GooglePushMessage message = new GooglePushMessage(data, TimeSpan.FromHours(1));
Services.Push.SendAsync(message);
but there is no way to pass in the registration ID.
UPDATE
I've also tried using the payload property of GooglePushMessage:
GooglePushMessage message = new GooglePushMessage();
message.JsonPayload = JsonConvert.SerializeObject(new { registration_id = "blablabla", data = new { message = "77" } });
It turns out that it is ignoring the registration_id property, because I'm still getting the notification on my device.
What I want to achieve is to get API calls from third parties and use the registration ids that I have stored in my DB to send notifications to specific devices.
Mobile Services uses Notification Hubs to handle it's push notifications. Notification Hubs filters push (i.e. does targeted push to specific devices, users, etc) using a Tag system. So if you want to be able to push to a specific Android Registration ID, when the device registers for Push Notifications with your Mobile Service, you should specify tags that you want to tie your registration to like so:
ToDoActivity.mClient.getPush().register(gcmRegistrationId, "tag1", "tag2");
If you want to push based off of the registration ID, you'd use that ID as one of your tags. Then from your .NET backend, when you call SendAsync, you can specify a tag (or tag expression) to target a specific device. So our call to push becomes:
Services.Push.SendAsync(message, registrationID);
The above text was incorrect. Tags are limited to 120 characters (https://msdn.microsoft.com/en-us/library/dn530749.aspx) and the GCM registration ID is too long for this. TODAY you're stuck with using an alternate tag that is less than 120 characters. If you have a UserID that is known on the device you could use that as a tag and then from your backend you can push to that specific User ID. Alternatively, you could generate a GUID on app launch and use that as a tag and then from your backend push to that GUID whenever you wanted to reach the specific device.
Related
I am following the Azure Mobile Services e-book for setting up Push Notifications:
https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter5/android/#registering-for-push-notifications
But am having problems with registering with a Tag:
var registrationId = GcmClient.GetRegistrationId(RootView);
//var push = client.GetPush();
//await push.RegisterAsync(registrationId);
var installation = new DeviceInstallation
{
InstallationId = client.InstallationId,
Platform = "gcm",
PushChannel = registrationId
};
// Set up tags to request
installation.Tags.Add("topic:Sports");
// Set up templates to request
PushTemplate genericTemplate = new PushTemplate
{
Body = #"{""data"":{""message"":""$(message)""}}"
};
installation.Templates.Add("genericTemplate", genericTemplate);
// Register with NH
var response = await client.InvokeApiAsync<DeviceInstallation, DeviceInstallation>(
$"/push/installations/{client.InstallationId}",
installation,
HttpMethod.Put,
new Dictionary<string, string>());
I have ensured that the tag is listed in the Azure Portal as a "Client Requested" tag, but still my registrations appear without the tag in the Device Registrations:
Any ideas what I am doing wrong?
It would appear that the e-book is out of date and is dealing with the old version of Mobile Services instead of Azure App Service Mobile Apps (seriously, how is anyone supposed to google around for the different versions when they are named so similarly?!)
https://github.com/Azure-Samples/app-service-mobile-dotnet-backend-quickstart/blob/master/README.md#push-to-users
(Emphasis is mine)
When a mobile app registers for push notifications using an Azure App Service Mobile Apps backend, there are two default tags that can get added to the registration in Azure Notification Hubs: the installation ID, which is unique to the app on a given device, and the user ID, which is only added when the user has been previously authenticated. Any other tags that get supplied by the client are ignored, which is by design. (Note that this differs from Mobile Services, where the client could supply any tag and there were hooks into the registration process on the backend to validate tags on incoming registrations.)
Because the client can’t add tags and at the same time there are no service-side hooks into the push notification registration process, the client needs to do the work of adding new tags to a given registration.
So the reason it was not working was because the code in the e-book is out of date and does not work with the latest version.
I had to create an Api Controller to allow the Tag to be registered using the code in the above link. Then the client apps have to call this endpoint just after they have called the two commented methods in the sample code in my question.
I have Android app, which is working with Azure IoT hub.
There are several tables on Azure, one of which stores credentials of registered users of my app. This table has one column called "userId" and records are unique here.
I also have node.js script which will be processing data in one of the tables and sending push notifications based on that data via GCM.
function sendPush(userId, pushText)
{
var payload = pushText;
push.gcm.send(null, payload, {
success: function(pushResponse) {
console.log("Sent push:", pushResponse, payload);
request.respond();
},
error: function (pushResponse) {
console.log("Error Sending push:", pushResponse);
}
});
}
I know that to make targeted push notification with Google Cloud Messaging, you have to get token with InstanceID class.
But can I somehow use "userId" column record to become that token to make my push notification targeted?
Generally speaking, you can leverage Tags param as tag identifier to push notifications to specified device. Refer to Sending push notifications with Azure Notification Hubs and Node.js for more.
And you can register with tags from your backend application, if your requirements are in the proper scenarios listed at https://msdn.microsoft.com/en-us/library/azure/dn743807.aspx
In backend nodejs application, you can try to use following code to register with tags:
var notificationHubService = azure.createNotificationHubService('<nb-name>', '<nb-keys>');
notificationHubService.createRegistrationId(function(err,registerId){
notificationHubService.gcm.createNativeRegistration(registerId,"identifier-tags",function(err,response){
console.log(response)
})
})
Then you can try to use the tags in send function.
Any further concern, please feel free to let me know.
I'm building an application using Ruby On Rails. the app is supposed to push notifications to android and IOS user using Parse RESTfull api. i have tried to use parse-ruby-client but the documentation is poor and a don't get how it really works. i mean how to send a notification a specific user.
In order to send a notification to a specific user you first need to have channels for each user setup or query a specific installation. With parse and the rest api the easiest way I have found to send a notification to an individual user is to setup each user as a channel. When the user initially sets up the app on their device, I take either their username or email and use that as their channel. Then when I want to send a notification to a specific user I send to that channel.
In ruby to send to a channel you would use the following substituting your channel in place of Giants
data = { :alert => "This is a notification from Parse" }
push = Parse::Push.new(data, "Giants")
push.type = "ios"
push.save
For advanced targeting, for example, if you want to query a class and find iOS users with injury reports set to true you can use the following:
data = { :alert => "This is a notification from Parse" }
push = Parse::Push.new(data)
push.type = "ios"
query = Parse::Query.new(Parse::Protocol::CLASS_INSTALLATION).eq('injuryReports', true)
push.where = query.where
push.save
The push.type refers to the system type- iOS (ios), android (android), windows user (winrt or winphone).
In Android L Preview doc,
https://developer.android.com/preview/notifications.html
there is a mention of "Cloud-synced notifications - act on a notification on your Android tablet and it is also dismissed on your phone." but no detailed information on it.
Any idea where can I find more information about this and how to implement this new feature in my app ?
This can be achieved with User Notifications, which is a feature of Google Cloud Messaging.
The idea is that your server registers a group of devices (identified by their GCM registration ID) that belong to the same user and gets a single notification ID for that user. Then you can send a GCM message to all the devices of that user using that single notification ID. This message can be sent either from your server to all devices of the user or from one device to the other devices of that user.
When one device handles the notification, you can send a GCM message to all the other devices belonging to the same user, to let them know the notification was viewed on one device, and the other devices would receive that message and dismiss the notification.
To send an upstream (device-to-cloud) message, you must use the GoogleCloudMessaging API. Specifying a notification_key as the target for an upstream message allows a user on one device to send a message to other devices in the notification group—for example, to dismiss a notification. Here is an example that shows targeting a notification_key:
GoogleCloudMessaging gcm = GoogleCloudMessaging.get(context);
String to = NOTIFICATION_KEY;
AtomicInteger msgId = new AtomicInteger();
String id = Integer.toString(msgId.incrementAndGet());
Bundle data = new Bundle();
data.putString("hello", "world");
gcm.send(to, id, data);
I have a single android application, which supports for 7 countries(Localization and Internationalization). The application functionality and language changed based on the device locale.
I need to implement the GCM push notifications for this application.
Requirement:
Is it possible to send the push notification in 7 different languages with single GCM account.
Is there any way to display the push notification in their device local language.
You can either take the approach suggested by Ascorbin, or implement something similar to what Apple have in their push notifications:
Your server can send a GCM message with a parameter that is a key to a message. Yout Android App will have to contain for each possible key the strings that should be displayed for it in each of the 7 languages (using multiple copies of strings.xml). Then the GCM reciever in your app will get the key from the server and get the resource string that matches it (it will automatically get the string that matched the locale of the device). This way you don't have to worry about localization in your server. The downside of this approach is that all your messages have to be predefined in your app.
You can also add parameters to the message key like Apple do.
For example, the server sends a key = "NEW_MAIL_FROM" and param1 = "John". The app finds a string resource for that key (lets assume the device used English locale) - "You have a message from {0}" - and replaces the param with John, displaying the message "You have a message from John". A device with a differennt locale will show a message in a different language.
You can implement that server-side, after GCM registration with the send of token, send also the device locale. And then notify users instantly with a localized message.
Payload is something "sort" its not a good idea to pass through it so much information.
On the other hand if you have fixed messages you can use:
private void handleMessage(Intent intent) {
// server sent key-value pairs
String name_of_resource = intent.getExtra("message_id");
int id = getResources().getIdentifier(name_of_resource, "string", getPackageName());
if (id != 0) {
String text = getString(id); // the text to display
// generates a system notification to display here
}
}
see http://developer.android.com/google/gcm/gcm.html#received_data for handling received data.
When the devices register at your server, let them send the Locale. So you can have locale groups of devices and send the messages in according languages.
You can easily localize your GCM notification using title_loc_key and body_loc_key. These keys listed in official GCM docs.
More details can be found here.
Send a GCM Push from server (without any language specific data).
In response to the push, the client makes a REST api call to the server with it's language as a Query parameter.
The server fetches appropriate language's text and send back to the client on real time.