Unable to Register IOS device to Mobile First 8 - ibm-mobilefirst

I am able to see the iOS device under devices tab in MF, registered to my application. but pushing a notification fails with the below error:
An error occurred while the notification was sent. Internal server error. No devices found.
Upon reviewing IOS code, I noticed the below issue while invoking MFPPush.sharedInstance.registerDevice(nil)
Cannot retrieve a valid authorization header for header. Check resource and authorization server configuration.
I am using the code from the git sample. Below is the snippet throwing the error:
#IBAction func registerDevice(_ sender: AnyObject) {
print("Attempting Device registration with Mobile First")
WLAuthorizationManager.sharedInstance().obtainAccessToken(forScope: "push.mobileclient") { (token, error) -> Void in
if (error != nil) {
print("Did not recieve an access token from server: " + error.debugDescription)
} else {
WLClient.sharedInstance()?.setDeviceDisplayName("White Ipad", withCompletionHandler: { (error) in
if error == nil{
print("device display name is set")
}else{
print("error setting device name: " + error.debugDescription)
}
})
print("Recieved the following access token value: " + (token?.value ?? "no token"))
MFPPush.sharedInstance().registerDevice(nil) { (response, error) -> Void in
if error == nil {
self.enableButtons()
self.showAlert("Registered successfully with Mobile First")
print(response?.description ?? "")
} else {
self.showAlert("Registration failed with Mobile First. Error \(error?.localizedDescription)")
print(error?.localizedDescription ?? "")
}
}
}
}
}
Mobile First Config: I have followed the documentation and configured the UserLogin security check from the sample git project and have removed scope to push.mobileclient under security.
Reading the OAuth Security in MF, i understand the that token is necessary to access resources, but I am unable to figure out how to attach the token in registerDevice().

It seems to be you haven't configured Push Notifications properly in MobileFirst Server.
Make sure that you have added push.mobileclient scope in Security tab of your application. If you are not using any security check, you can add scope like below.
Check whether your application is configured valid iOS provisioning profile enabled with Push Capability
Make sure that you have uploaded valid sandbox/production certificates in Push tab of your particular app in MFP Operations Console.
More details : here
Make sure your app is enabled Push Capability in the project setting and also check you sending device token to MF Server using MFPPush.sharedInstance().sendDeviceToken(deviceToken) API in didRegisterForRemoteNotificationsWithDeviceToken method of AppDelegate file
-

Related

Authentication Service throws Procedure invocation error post upgrade from MFP 6.3 to MFP 7.1

Authentication adapter throwing "Procedure invocation error" sometimes. Tried clearing cache and cookies but still the same. So we tried to login from different system for same user and it works. This is quite confusing as once we try with different ID in browser where issue occurred, it works and then it works with Member ID which has issue as well. Auth required is not coming in response when issue occurs.
we have tried to look into logs and found WorklightAuthenticationException from Authentication Adapter while trying security test procedure.
Authentication Adapter code:
var result = WL.Server.invokeHttp(input);
WL.Logger.info("Authentication service : " + JSON.stringify(result));
authResponse = prepareJSONResponse(result,channelId);
WL.Logger.info('Formatted response -> ' + JSON.stringify(authResponse));
if(result.isSuccessful == false){
WL.Logger.info("Error: " + result.errorMessage);
return onAuthRequired(null, "Error in connecting to server. Please try again later.");
}
if(typeof authResponse.errorMessage != 'undefined'){
WL.Logger.info("Error is defined" +authResponse.errorMessage);
return onAuthRequired(null, authResponse);
}
WL.Logger.info("Authentication service success: " + JSON.stringify(result));
WL.Logger.info("userIdentity Parameters: " + inputParams.CorpId);
var userIdentity = {
userId: inputParams.CorpId,
displayName: inputParams.CorpId,
attributes: {
foo: "bar"
}
};
WL.Logger.info("userIdentity::"+JSON.stringify(userIdentity));
WL.Server.setActiveUser("SingleStepAuthRealm", userIdentity);
return {
authRequired: false
};
It is happening due to the requests going from one node to another node. Handled it in Load balancer to send requests to specific node based on cookies and post that it works fine.
The description mentions about clearing cache and cookies and using browser.
Browser based environments are not supported in session independent mode. These work only in session dependent mode. As such, it is imperative that session based affinity be enabled to ensure the requests land in the same JVM for authentication state to be preserved.
More details can be found here : Session-independent mode

AWS Cognito Auth token - swift

I have successfully created a Cognito user pool and identity pool using aws amplify, and am able to use the documented process to login using the provided authUI. Once logged in, I can retrieve a jwt token via the provider response.... (not complete below so ignore any syntax errors)
AWSAuthUIViewController.presentViewController(
with: self.navigationController!, configuration: nil,
completionHandler: { (provider: AWSSignInProvider, error: Error?) in
if error != nil {
print("Error occurred: \(String(describing: error))")
} else {
// Sign in successful.
print("sign in - token = \(provider.token())")
var tokentask = provider.token()
var output = tokentask.result
}
})
I can then use that token (output) to authentication against an API gateway resource successfully. My problem is I cannot get the token at any other time. I cannot find the correct object to use to try to retrieve that token or cannot find the location where the token is cached so I can reuse it at other times in the app. Any assstance would be appreciated!
i've managed to find out the best way -
AWSCognitoUserPoolsSignInProvider.sharedInstance().getUserPool().token().continueWith { (AWSTask) -> Any? in
if AWSTask.error == nil {
print("Token \(String(describing: AWSTask.result))")
}
return nil
}
This returns the token via awstask.

Preview not working properly in MFP8.0

I'm developing an application that just connects to MFP 8.0 server but when I run the app using the MFP web simulator the log says "getCachedAccessToken for scope failed: undefined" . But when I run the same application using the emulator/device it works fine.
function wlCommonInit() {
WLAuthorizationManager.obtainAccessToken().then(
function () {
alert ("You are now connected to the server");
},
function(result) {
alert("Not able to connect: "+ JSON.stringify(result));
}
);
}
Is there any way to test the MFP server connection in the MFP web simulator?
This is a known limitation of the 8.0 release.
You can read more about it, here: http://engtest01w.francelab.fr.ibm.com:9090/support/knowledgecenter/SSHS8R_8.0.0/com.ibm.worklight.dev.doc/wl_studio_tools/topics/cmbswl.html
Tokens are part of the OAuth flow.
As a workaround, you can use a simulator.

PNAccessDeniedCategory for sending the message in pubnub objective c

I am trying to send the message by using pubnub.
But it gives me error for : PNAccessDeniedCategory
I am not finding any solution how to solve this.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
PNConfiguration *configuration = [PNConfiguration configurationWithPublishKey:#"pub-c-..."subscribeKey:#"sub-c-..."];
self.client = [PubNub clientWithConfiguration:configuration];
//Subscription process results arrive to listener which should adopt to PNObjectEventListener protocol and registered using:
[self.client addListener:self];
//Listeners callbacks:
[self.client subscribeToChannels: #[#"test123"] withPresence:YES];
NSLog(#"channel-->%#",self.client.channels);
configuration.uuid = #"test123";
}
- (void)client:(PubNub *)client didReceiveStatus:(PNSubscribeStatus *)status {
if (status.category == PNUnexpectedDisconnectCategory) {
// This event happens when radio / connectivity is lost
}
else if (status.category == PNConnectedCategory) {
// Connect event. You can do stuff like publish, and know you'll get it.
// Or just use the connected event to confirm you are subscribed for
// UI / internal notifications, etc
}
else if (status.category == PNReconnectedCategory) {
// Happens as part of our regular operation. This event happens when
// radio / connectivity is lost, then regained.
}
else if (status.category == PNDecryptionErrorCategory) {
// Handle messsage decryption error. Probably client configured to
// encrypt messages and on live data feed it received plain text.
}else if (status.category == PNAccessDeniedCategory) {
Nslog(#"It gives me this error");
}
}
Please advice. Whether this error is because my account is expired and that is the reason it is not allowing me to access ?
Do i have to create another free account ? or have to create new key ?
Please help.
PubNub Access Manager
You have Access Manager add-on enabled on your keys and so it is just doing its job - denying un-granted access to your keys. You must grant all access to use your keys once this is enabled. When you enable Access Manager a dialog pops up with a warning:
Warning: This action will enable Access Manager on your keyset. If you
are already using this keyset in a production application, please be
aware you will need to grant access to all existing channels in order
to continue use without interruptions.
Here is a snapshot of that dialog:
You can disable Access Manager until you are ready to implement the proper granting logic on your server and you will no longer get this error.
Before you go live with your app, you should implement the necessary granting logic and enable Access Manager to protect your keys from being wrongfully used.

How to get mobile reistration ID using GSM Titanium?

I am developing android app in titanium,by button click event I have to get registration ID from GCM. how to do that I am new to titanium.
I followed this http://iamyellow.net/post/40100981563/gcm-appcelerator-titanium-module, but I am not able to understand how to implement?
Thanks in advance.
To implement push notification, you should use Ti.CloudPush module.
You can achieve GCM Push Notification in 6 easy steps
Setting up Google Cloud Messaging
Push Configuration in ACS Console
CloudPush Module Implementation
Retrieve Device Token
Cloud User Login
Subscribe a Channel
1. Setting Up GCM
To use GCM, you need to create a Google API project to obtain a Google API key and GCM sender ID. For instructions on creating and obtaining these items, see Android Developer: Getting Started with GCM and follow the directions in "Creating a Google API Project", "Enabling the GCM Service" and "Obtaining an API Key".
We will use our Project number as GCM Sender ID.
When creating a new server key, you are asked for a list of IP addresses to accept requests from. Do not enter any information in the textbox and click Create to accept all IP addresses.
2. Push Configuration in the ACS
Go to your apps, then go to My Apps -> Manage ACS -> DEVELOPMENT -> Settings/Android Push Configuration and enter your Google API key in the Google Cloud Messaging (GCM) API Key textbox and GCM sender ID in the Google Cloud Messaging (GCM) Sender ID textbox. (which we got from Step 1)
3. CloudPush Module Implementation
Add CloudPush module into your application.
To add CloudPush module, you need to add <module platform="android">ti.cloudpush</module> in your TiApp.xml. Then require the module in your javascript file using var CloudPush = require('ti.cloudpush');.
To use push notifications, in the tiapp.xml file, you need to specify push type to GCM.
To do this go to your tiapp.xml.
Add/edit the following lines
<property name="acs-push-type-development" type="string">gcm</property>
<property name="acs-push-type-production" type="string">gcm</property>
<property name="acs-push-type" type="string">gcm</property>
4. Retrieve Device Token
Call the retrieveDeviceToken method before setting the enabled property to true to enable the device to receive push notifications. You must call retrieveDeviceToken before any other CloudPush API call or else the device will not receive push notifications.
var CloudPush = require('ti.cloudpush');
var deviceToken = null;
CloudPush.retrieveDeviceToken({
success: function deviceTokenSuccess(e) {
Ti.API.info('Device Token: ' + e.deviceToken);
deviceToken = e.deviceToken;
},
error: function deviceTokenError(e) {
alert('Failed to register for push! ' + e.error);
}
});
5. Cloud User Login
Before subscribe for Push Notification, cloud user should logg in.
Cloud.Users.login({
login: username,
password: password
}, function (e) {
if (e.success) {
alert("login success");
} else {
alert('Error: ' + ((e.error && e.message) || JSON.stringify(e)));
}
});
6. Subscribe a Channel
You need to subscribe to a channel to get the pushnotification. Push notification will be sending to the particular channel and it will be reached to all users who subscribed to the channel.
if(deviceToken != null){
Cloud.PushNotifications.subscribe({
channel: 'yourchannelName',
device_token: deviceToken,
type: 'gcm' //here i am using gcm, it is recommended one
}, function (e) {
if (e.success) {
alert('Subscribed for Push Notification!');
} else {
alert('Subscribe error:' + ((e.error && e.message) || JSON.stringify(e)));
}
});
} else {
alert('You need to retrieve the device token first');
}
Now you can send push notification. To do this go to My Apps -> Manage ACS -> DEVELOPMENT -> Push Notifications, here you can see number of clients subscribed for push notification, channels etc. You can send the push notification from there.
UPDATE : Attention!!
GCM supports devices that run Android 2.2 and later
Google Play Store application should be installed in your device.
For pre-4.0 devices, the user is required to set up their Google account.
You're using an android device for testing, not emulator(Since you can't install Google Play in your emulator).
Google play service is running on your device.
The following links will help you:
Titanium.CloudPush
Android SDK Titanium
ACS Push Notification Using GCM