NotificationHub Push Notification returns : The Token obtained from the Token Provider is wrong - push-notification

I have Wp8.1 Silverlight app that receives push notification (WNS) from Mobileservice (the old azure service).
I therefore wanted to update to the new service because of the new features. I have now created/upgraded a new server to use App Service - Mobile App. And tested push notification with the sample app from azure (everything works).
Going back to my app WP8.1 -> Adding the new package Microsoft.Azure.Mobile.Client through NuGet (2.0.1), there is the issue that the Microsoft.WindowsAzure.Mobile.Ext does not contain the 'GetPush' extension. It seems like it is missing it? looking to the WP8 version, it only registers to MPNS, and I need WNS. So I do not know if any other assembly could be used.
Can I add another assembly reference?
Update
The following code lets me register the device on the server, and I can see the device register correctly. where the channelUri and the installationInformation are retrieved by the client and send to the server.
Installation ins = new Installation();
ins.Platform = NotificationPlatform.Wns;
ins.PushChannel = uTagAndChan.ChannelUri;
ins.Tags = uTagAndChan.Tags;
ins.InstallationId = uTagAndChan.installationInformation;
await hubClient.CreateOrUpdateInstallationAsync(ins);
Sending a test toast-notification to the registered tags, results in the following error :
The Token obtained from the Token Provider is wrong
Searching on this issue I found Windows Store App Push Notifications via Azure Service Bus. Which the proposed solution says to register to the notification hub directly from the app, I would rather not have the app to have directly access to the hub. But is this the only way? (mind you the answer was not accepted, but I will try it all though it is not a desired solution)
Update
Registering for notifications via client (WP8.1 Silverligt), makes a registration to MPNS, which I do not want.
The snippet on the server registers a WNS, the two registrations can be seen here:
The URI retrieval is done using
var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
which in the description states it returns a WNS. This seems to infer that the registration I am doing on the server (code snippet in the top) is correct and the registration on the client is faulty.
But the registration on the image seems wrong. Shouldn't the PNS Identifier be different for the two registrations? also expiration date seems wrong ?
How to mend this since the GetPush() (which was available in the sample registered the client correctly for notifications) does not exist in the NuGet package?
Update
I read one place that deleting and recreating the NotificationHub could help. I will try this today. Even IF it works, it would be more desirable to have the solution, and to know if the registrations are done correctly?
Temporary solution:
Deltede, recreated, inserted Package SID and Secret. And it works again (strange)!
Still interested in the underlying issue!

Deleted and recreated the service, setting all the same settings made it work again.

I had same issue with my UWP. But in my case I had issue with self signed certificate.
When I set the AppxPackageSigningEnabled property to True (in .csproj) then notifications stopped working and I got "The token obtained from the Token Provider is wrong" (Test send from Azure Portal).
The certificate must have same issuer as Publisher in Identity element in .appxmanifest file.

Related

GetTwinAsync() are not supported in IoT edge Simulator v0.14.10

GetTwinAsync() returns always Twin object with empty properties, all properties of my IoT edge module are null when I run my IoT edge device in Simulator, in my Linux server works everything fine. I should wait also about 20 seconds to get a response from GetTwinAync().
If we look at it, this problem is expected. If you read this Understand and use module twins in IoT Hub document, then you will see that from module app, only has permission to read desired properties and read/write reported properties. If you check this image below you will understand better.
The lifecycle of a module twin is linked to the corresponding module identity. Modules twins are implicitly created and deleted when a module identity is created or deleted in IoT Hub.
To access all module properties, you can do it from solution back end and require the ServiceConnect permission. You will need Microsoft.Azure.Devices V1.16.0-preview-001 or later. The following is a console app code snippet.
...
RegistryManager registryManager = RegistryManager.CreateFromConnectionString(connectionString);
Module module;
try
{
module = await registryManager.AddModuleAsync(new Module(deviceID, moduleID));
}
catch (ModuleAlreadyExistsException)
{
module = await registryManager.GetModuleAsync(deviceID, moduleID);
}
...
For more detailed explanation and example check this Get started with IoT Hub module identity and module twin (.NET). If your issue still persist then you can open an issue on azure-iot-sdk-csharp repository.

Azure Notification Hub device registration

Since AppCenter retiring at the end of this year, I have started migrating to Azure-Notification-Hub.
But the documentation for notification-hub is not clear at all. Especially the documentation for Xamarin.Android. It does not match with their latest SDK.
In the latest (version 1.1.1) azure-notification-hub SDK for Android (or Xamarin.Android) there's no need to implement FirebaseMessagingService. NotificationHub.Start() method registers the device in the Notification-Hub. A device registered with this way gets notifications without any problem.
NotificationHub.Start(Application, <HubName>, <ConnectionString>);
Addition tags to existing NotificationHub instance are also straightforward with the new SDK.
NotificationHub.AddTag("username:user123");
But in Registration Management official doc states that devices can register with the notification-hub either from client-side or from server-side. Is it necessary to use one of those methods if my app registered with the notification-hub using the NotificationHub.Start() method? Or do I missing something?
Also, when I was using the AppCenter, I have used the AppCenter-InstallId to target a specific device.
With that in mind is it possible to use the NotificationHub.InstallationId to use as a tag (eg: "handle:<devce's InstallationId>") to send device-specific notifications?
Is it necessary to use one of those methods if my app registered with the notification-hub using the NotificationHub.Start() method?
When you invoke NotificationHub.start(Application, ...), the Android SDK will listen for changes like added tags, new FirebaseMessagingService tokens, etc. Anytime it detects a change, it will invoke an InstallationAdapter to inform a backend of the new details.
The default InstallationAdapter will send an PUT request to the Azure Notification Hubs backend as documented here. This is what is created by NotificationHub.start(Application, string, string); for people who are not hosting their own backend, this is a sensible default.
If you have your own backend where you track devices, or you're just looking to keep your credentials server-side, you can swap out the InstallationAdapter to be a class that invokes your API. All you need to do is implement the InstallationAdapter interface and initialize the SDK by calling NotificationHub.start(Application, InstallationAdapter).
If you use the NotificationHub.start(...) methods as indicated above, there is no further registration action required.
With that in mind is it possible to use the NotificationHub.InstallationId to use as a tag (eg: "handle:<devce's InstallationId>") to send device-specific notifications?
Yes! This documentation walks you through how to use the special tag format $InstallationId:{YOUR_TAG_ID} to target a specific device.
When you've used NotificationHub.start(), if you do not specify an InstallationId, it will generate one for you.
Question about setting the InstallationId and/or UserId. If I'm using Microsoft.Azure.NotificationHubs.Client, which makes more sense to do.
Should I set the InstallationId via the $InstallationId Tag (see here: https://learn.microsoft.com/en-us/azure/notification-hubs/notification-hubs-push-notification-registration-management#installations) or via implementing the InstallationEnrichmentAdapter and set it via a call to installation.InstallationId = in the EnrichInstallation method?
Additionally, the Microsoft.Azure.NotificationHubs.Client.Installation class provides a UserId property that can be updated too.
I'm also moving my push notifications from AppCenter to Azure Notification Hub and want to reuse my existing AppCenter InstallId.
i am able to add tags and userid as below(java)
NotificationHub.start(this.getApplication(), BuildConfig.hubName, BuildConfig.hubListenConnectionString);
NotificationHub.setInstallationId("123");
Set<String> tags = new HashSet<>();
tags.add("role_memeber");
NotificationHub.setUserId("123");
NotificationHub.addTags(tags);
sdk: com.microsoft.azure:notification-hubs-android-sdk:1.1.6

How to knit dynamic reports with Google Analytics (rga)

I'm using rga to get some data from Google Analytics. From the repo:
The principle of this package is to create an instance of the API Authentication, which is a S4/5-class (utilizing the setRefClass). This instance then contains all the functions needed to extract data, and all the data needed for the authentication and reauthentication. The class is in essence self sustaining.
The package creates and saves a local instance using:
rga.open(instance="ga", where="~/ga.rga")
When I try to knit, however, I get an error that the ga object (what would be the instance) is not found. The code works when I run the chunks in RStudio, however—I believe the error is related to this aspect:
[The command above] will check if the instance is already created, and if it is, it'll prepare the token. If the instance is not created [...] it will redirect the client to a browser for authentication with Google.
My guess is that knitr can't perform that last step and so, the object is never created.
How can I make this work? I'm thinking that there might be a way to load the local ga.rga file to bypass browser authentication.
You can bypass browser authentication by passing the client id and client secret key that you can get it from Google API console. Saving a local auth file in the dev env is always risky. You can try this code, this uses Google API and also saves the local instance -
rga.open(instance = "ga",
client.id = "<contains apps.googleusercontent.com>",
client.secret =<your secret key>, where ="~/ga.rga" )
Also ensure that desktop option setting is enabled in Google API console

Check if a user is currently online to meteor server

I'd like to determine if a user is currently "online" or connected to the Meteor server.
I need this information before I send the user message, If the user is not connected I'd like to send the message via email.
I know that for traditional web applications that are totally state-less the definition of "online" use is a bit not clear but since modern web frameworks rely on websocket, a user is supposed to be online if a websocket is open.
The question is does Meteor include a method to determine if a user is connected or not?
Summarized: yes, there is such a mechanism.
There are for example package, that store the active login connections of the users with the meteor server and make them available either via an own collection or as part of the user profile.
See: https://github.com/dburles/meteor-presence
(Creates a new collection, called Presences)
or https://github.com/dan335/meteor-user-presence/
(Creates a user's profile entry, called presence. However, has also a collection to store and update the information in the background)
or https://github.com/mizzao/meteor-user-status
(Thanks to blueren in the comments)
Code example (from the first listed package)
Meteor.onConnection(function(connection) {
// console.log('connectionId: ' + connection.id);
Presences.insert({ _id: connection.id });
connections[connection.id] = {};
tick(connection.id);
connection.onClose(function() {
// console.log('connection closed: ' + connection.id);
expire(connection.id);
});
});
If you don't want to rely on the packages you may make use of that mechanism yourself.
See: https://docs.meteor.com/api/connections.html#Meteor-onConnection

Guidelines for robust synchronisation of mobile client (iOS, Swift) with Realm Object Server

I have used the techniques in the RealmTask tutorial (https://realm.io/docs/tutorials/realmtasks/ ) to get a demonstration of synchronisation with the Realm Object Server working. However, as mentioned in realm mobile platform, how to connect while offline? , it is difficult to find design guidelines on realising a robust app in the presence of intermittent network connectivity. For example, the network might not be available when the app is first run, and in the tutorial example I think the login attempt would just time out after say 30 seconds.
From various sources, I have tried to outline an implementation approach on the client and have come up with the following:
=============================================================
At start-up of app
Create login credentials with
SyncCredentials.usernamePassword()
Check whether user credentials already exist using
SyncUser.all
If so, get the correct user using the appropriate key (UserId)
If a user is obtained, get the Realm configuration using
realmConfiguration = Realm.Configuration(SyncConfiguration(user, realmURL))
Attempt a log-in with
SyncUser.logIn with SyncCredentials
On completion, put the following on the main DispatchQueue (async)
realmConfiguration = Realm.Configuration(SyncConfiguration(user, realmURL))
if not logged in, repeat login attempts every N minutes until successful? E.g. to handle the situation when the network is unavailable when the app is started, but then becomes available?
Launch the rest of the app, making realmConfiguration available.
However, only access the Realm if realmConfiguration has been set up. Design the app so that it handles the scenario of realmConfiguration not being set up.
=============================================================
Is the above approach sensible, or is there a better solution?
Katsumi from Realm here. Our RealmTasks demo application may help you.
https://github.com/realm-demos/realm-tasks/tree/master/RealmTasks%20Apple
First, check whether the user has logged in or not at launched the app.
if configureDefaultRealm() {
window?.rootViewController = ContainerViewController()
window?.makeKeyAndVisible()
} else {
window?.rootViewController = UIViewController()
window?.makeKeyAndVisible()
logIn(animated: false)
}
https://github.com/realm-demos/realm-tasks/blob/master/RealmTasks%20Apple/RealmTasks%20iOS/AppDelegate.swift#L35
If the user has been logged in before, you can use user object that was cached before. (SyncUser.current or SyncUser.all)
If there is no cached user object (The user is the first time to use the app, or the user re-installs the app), show login view to signing up/in.
The former case (Use the cached user object) doesn't require network access, so you don't need to care about the offline situation.
The latter case (The user should signing up/in) requires network access, in that case, the best practice depends on the specification of the app. It is enough to show a just alert view that indicates requiring network for some apps, or use standalone Realm and then migrate synced realm after the app will be online.

Resources