JSON Store is not creating in Android for latest version fix pack 7.1.0.00.20160919-1656 - ibm-mobilefirst

Below sample code is not working in latest fix on Android but if we remove the password field from options then it's working fine. We are getting below error on Android but it's working fine on IOS
{"src":"initCollection","err":-3,"msg":"INVALID_KEY_ON_PROVISION","col":"people","usr":"test","doc":{},"res":{}}
function wlCommonInit(){
/*
* Use of WL.Client.connect() API before any connectivity to a MobileFirst Server is required.
* This API should be called only once, before any other WL.Client methods that communicate with the MobileFirst Server.
* Don't forget to specify and implement onSuccess and onFailure callback functions for WL.Client.connect(), e.g:
*
* WL.Client.connect({
* onSuccess: onConnectSuccess,
* onFailure: onConnectFailure
* });
*
*/
// Common initialization code goes here
}
function onClick(){
alert("Click");
var collectionName = 'people';
// Object that defines all the collections.
var collections = {
// Object that defines the 'people' collection.
people : {
// Object that defines the Search Fields for the 'people' collection.
searchFields : {name: 'string', age: 'integer'}
}
};
// Optional options object.
var options = {
username:"test",
// Optional password, default no passw`enter code here`ord.
password : '123',
};
WL.JSONStore.init(collections, options)
.then(function () {
alert("Success in jstore");
})
.fail(function (errorObject) {
// Handle failure for any of the previous JSONStore operations (init, add).
alert("Failure in jstore : "+ JSON.stringify(errorObject));
});
};

Update: The iFix is now released. Build number is 7.1.0.0-IF201610060540 .
This is a known issue with the latest available iFix. It has been recently fixed and should be available soon.
Keep an eye out for a newer iFix release in the IBM Fix Central website for a fix for this issue.

Related

Resolving audio broadcasting error: client join failed DYNAMIC_KEY_EXPIRED (Agora.io)

I'm a server side developer with rudimentary JS knowhow. I'm tinkering with Agora's audio broadcasting functionality (specifically for the web). For reference, I've been following this: https://docs.agora.io/en/Audio%20Broadcast/start_live_audio_web?platform=Web
I'm attempting to broadcast audio as a host. I have an HTML button which fires a JS function where I:
Initialize a client
Set the role
Join a predefined channel
Publish a local stream
My understanding is that accomplshing the aforementioned will enable me to broadcast audio. When I try this, I end up getting a client join failed DYNAMIC_KEY_EXPIRED error. I'm unable to find documentation regarding how to resolve this. Can you help me resolve this? An illustrative example would be nice.
My JS code is below. Note that I'm using a temp token to test this functionality on localhost.
// rtc object
var rtc = {
client: null,
joined: false,
published: false,
localStream: null,
remoteStreams: [],
params: {}
};
// Options for joining a channel
var option = {
appID: "anAppID",// from 'Project Management' dashboard
channel: "AudioLive",
uid: null,//The user ID should be unique in a channel. If you set the user ID as null or 0, the Agora server assigns a user ID and returns it in the onSuccess callback.
token: "aTempToken"// TEMP Token
}
function createBroadcast(role) {
console.log("entered createBroadcast");
// Create a client
rtc.client = AgoraRTC.createClient({mode: "live", codec: "h264"});
// Initialize the client
rtc.client.init(option.appID, function () {
console.log("init success");
// Note: in a live broadcast, only the host can be heard and seen. You can also call setClientRole() to change the user role after joining a channel.
rtc.client.setClientRole(role);
console.log("role is set");
// Call Client.join in the onSuccess callback of Client.init
rtc.client.join(option.token ? option.token : null, option.channel, option.uid ? +option.uid : null, function (uid) {
console.log("join channel: " + option.channel + " success, uid: " + uid);
rtc.params.uid = uid;
// Call AgoraRTC.createStream to create a stream in the onSuccess callback of Client.join
rtc.localStream = AgoraRTC.createStream({
streamID: rtc.params.uid,
audio: true,
video: false,
screen: false,
})
// Call Stream.init to initialize the stream after 'creating' the stream above
// Initialize the local stream
rtc.localStream.init(function () {
console.log("init local stream success");
// play stream with html element id "local_stream"
rtc.localStream.play("local_stream");
// Call Client.publish in the onSuccess callback of Stream.init to publish the local stream
// Publish the local stream
rtc.client.publish(rtc.localStream, function (err) {
console.log("publish failed");
console.error(err);
})
}, function (err) {
console.error("init local stream failed ", err);
});
}, function(err) {
console.error("client join failed", err)
})
}, (err) => {
console.error(err);
});
}
<div style="background:#f0f3f4;padding:20px">
<button id="broadast" style="height:40px;width:200px" onclick="createBroadcast('host')">Start Live Broadcast</button>
</div>
I've not added the actual values for appID and token in the code above.
Note: Please ask for more information in case you require it.
The error that you are facing is due to the expiry of the token generated for authentication purposes while generating an APP ID. To resolve this you will have to generate a new token as elaborated in the below given links:
Token-expired
renewToken
A token (or a temporary token) expires after a certain period of time. When the SDK notifies the client that the token is about to expire or has expired by the onTokenPrivilegeWillExpire or onTokenPrivilegeDidExpire callbacks, you need to generate a new token and call the renewToken method.
client.on("onTokenPrivilegeWillExpire", function(){
//After requesting a new token
client.renewToken(token);
});
client.on("onTokenPrivilegeDidExpire", function(){
//After requesting a new token
client.renewToken(token);
});
Include the above functions in your javascript code along with the rest of the eventListeners.
Incase your application doesn't require security you can opt to not use a token and generate an App ID without a certificate.
App ID without certificate
Do get back for further support incase the issue remains unresolved.

AWS Cognito JS SDK returning "AdminUpdateUserAttributes is not a function" error message

I'm trying to create a function which allows me to update a user's phone number in a Cognito User Pool. The code is in a NodeJS application, using the latest aws-sdk library.
I have this function callback structure working for a number of other actions against the user pool, e.g. creating and listing users, updating MFA, etc. So I am confident there's nothing structurally wrong with the way I have laid the code out.
But for this particular function, I am receiving an error that says AdminUpdateUserAttributes "is not a function".
I've tried changing different attributes in case it's a phone number thing, but I got the same result.
function cognitoUpdatePhone(username, phoneNumber, callback) {
var params = {
UserPoolId: '<my pool Id>',
Username: username,
UserAttributes: {
phone_number: phoneNumber
}
};
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
cognitoidentityserviceprovider.AdminUpdateUserAttributes(params, function (err, data) {
if (err) {
callback(err, false);
}
else {
callback(null, true);
}
});
}
I'm getting following response from the server. The stack trace indicates the source of the error is: aws-sdk/lib/state_machine.js
message: 'cognitoidentityserviceprovider.AdminUpdateUserAttributes is not a function',
code: 'TypeError',
Encountered the exact same problem. Solved it by changing the first letter of the function to lowercase: adminUpdateUserAttributes
Try using this:
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});

hapi 18 eventsourcing not working without stream.end()

Try to archive:
I try to use the HTML5 EventSourcing API https://developer.mozilla.org/de/docs/Web/API/EventSource to push events to my client application (javascript).
working example code with plain node http:
With a plain example node implementation it works perfectly and as expected. Example code: https://www.html5rocks.com/en/tutorials/eventsource/basics/
Problem:
When i try to integrate EventSourcing (or SSE) into my API endpoint which is based on hapi (currently using latest - 18.1.0) it does not work.
My route handler code mixed with some code i found:
const Stream = require('stream');
class ResponseStream extends Stream.PassThrough {
setCompressor (compressor) {
this._compressor = compressor;
}
}
const stream = new ResponseStream();
let data = 0;
setInterval(() => {
data++;
stream.write('event: message\n');
stream.write('data:' + data + '\n\n');
console.log('write data...', data);
// stream.end();
}, 1000);
return h
.response(stream)
.type('text/event-stream')
.header('Connection', 'keep-alive')
.header('Cache-Control', 'no-cache')
Findings:
I already searched and it seems since hapi 17.x there they exposed the flush method for the compressor < https://github.com/hapijs/hapi/issues/3658 >, section features.
But it still does not working.
They only way it sends a message is to uncomment the stream.end() line after sending the data. The problem obviously is that i cant send further data if i close the stream :/.
If i kill the server (with stream.end() line commented) the data gets transmitted to the client in a "single transmission". I think the problem is is still somewhere with the gzip buffering even when flushing the stream.
There are some code examples in the hapi github but i got none working with hapi 17 or 18 (all exmaples where hapi =< 16) :/
Someone know how to solve the problem or has a working EventSource example with latest hapi? I would kindly appreciate any help or suggestions.
Edit - Solution
The solution from the post below does work but i had also an nginx reverse proxy in front of my api endpoint it seems the main problem was not my code it was the nginx which had also buffered the eventsource messages.
To avoid this sort of problem add in your hapi: X-Accel-Buffering: no; and it works flawless
Well I just tested with Hapi 18.1.0 and managed to create a working example.
This is my handler code:
handler: async (request, h) => {
class ResponseStream extends Stream.PassThrough {
setCompressor(compressor) {
this._compressor = compressor;
}
}
const stream = new ResponseStream();
let data = 0;
setInterval(() => {
data++;
stream.write('event: message\n');
stream.write('data:' + data + '\n\n');
console.log('write data...', data);
stream._compressor.flush();
}, 1000);
return h.response(stream)
.type('text/event-stream')
}
and this is client code just to test
var evtSource = new EventSource("http://localhost/");
evtSource.onmessage = function(e) {
console.log("Data", + e.data);
};
evtSource.onerror = function(e) {
console.log("EventSource failed.", e);
};
These are the resources that where I found my way to working example
https://github.com/hapijs/hapi/blob/70f777bd2fbe6e2462847f05ee10a7206571e280/test/transmit.js#L1816
https://github.com/hapijs/hapi/issues/3599#issuecomment-485190525

MFPPush.registerDevice wrapped by obtainAccessToken failed

I'm trying to run MFP8's push sample app of GitHub. But MFPPush.registerDevice method failed and error message "Failed to register device:" was shown.
function registerDevice() {
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
MFPPush.registerDevice(
null,
function(successResponse) {
navigator.notification.alert("Successfully registered");
enableButtons();
},
function(failureResponse) {
navigator.notification.alert("Failed to register");
console.log("Failed to register device:" +
JSON.stringify(failureResponse));
}
)
);
}
I read the MFP8 document and found the note below.
Note: Authenticated notifications are currently not supported in Cordova applications due to a defect. However a workaround is provided: each MFPPush API call can be wrapped by WLAuthorizationManager.obtainAccessToken("push.mobileclient").then( ... );. The provided sample application uses this workround.
The sample code is wrapped by WLAuthorizationManager.obtainAccessToken indeed. But I think MFPPush.registerDevice may be called before 'obtainAccessToken' completes because return value of MFPPush.registerDevice's method is specified as Promise.then() parameter instead of function that call MFPPush.registerDevice.
So I think the sample should be written as bellow,
function registerDevice() {
WLAuthorizationManager.obtainAccessToken("push.mobileclient").then(
function() {
MFPPush.registerDevice(
null,
function(successResponse) {
navigator.notification.alert("Successfully registered");
enableButtons();
},
function(failureResponse) {
navigator.notification.alert("Failed to register");
console.log("Failed to register device:" +
JSON.stringify(failureResponse));
}
)
);
}
}
Could anyone give me some advice about that?
There is additional information. In device log these messages were logged.
Of course, I registered UserLogin security check to MobileFirst Server and UserLogin challengeHandler is created in UserLoginChallengeHandler.js
(I have not changed except bundleId)
2018-02-10 19:42:47.271015+0900 PushNotificationsCordova[1273:1500711] Failed to register device:"Error Domain=com.ibm.mfp.push Code=5 \"Error authenticating client. Error is 'Challenge handler does not exist. There is no registered challenge handler with key UserLogin'.\" UserInfo={networkMetadata={\n \"$bytesSent\" = 120;\n \"$category\" = network;\n \"$outboundTimestamp\" = 1518259366869;\n \"$path\" = \"http://192.168.0.105:9080/mfp/api/preauth/v1/preauthorize\";\n \"$requestMethod\" = POST;\n \"$trackingid\" = \"F8FD4A96-B046-4DAD-87F6-7441E8426C2E\";\n}, NSLocalizedDescription=Error authenticating client. Error is 'Challenge handler does not exist. There is no registered challenge handler with key UserLogin'.}"

How to store the data in local device using JSONStore in worklight?

I'm doing Login Page in worklight using JavaScript and jquery, the username and password should validate the data getting from JSONstore?
How to store the data locally using JSONStore in worklight and how does i get the data from JSONStore while validating the username and password?
In below code where my data will store and get, if the username and password has typed where it validate:
var collections = {
people : {
searchFields : {name: 'string'}
},
orders : {
searchFields: {name: 'string'}
}
};
WL.JSONStore.init(collections)
.then(function () {
return WL.JSONStore.init(collections);
})
.then(function () {
return WL.JSONStore.init(collections);
})
.then(function () {
alert('Multiple inits worked');
})
.fail(function (err) {
lert('Multiple inits failed' + err.toString());
});
How to solve the issue?
You really should never ever store username and password locally in the device. That does not sound very secure...
Additionally, where is the username and password coming from? How should the logic be able to validate the credentials? It needs to compare whatever is inputted with something, to know that it is correct. An implementation cannot be done without otherwise, so you need to provide the answer to this...
In the meanwhile, you can take a look at the following tutorial: Offline Authentication.
The included sample application assumes you have first authenticated with a backend system, and later allows for authenticating locally, "offline", in case an Internet connection is not available. For this it uses JSONStore to securely authenticate.
The tutorial include a thorough implementation example, be sure to follow it, and to provide the missing information in your question.
This tutorial explains how to use the JSONStore API, including the Add method: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-1/foundation/data/jsonstore/jsonstore-javascript-api/
var collectionName = 'people';
var options = {};
var data = {name: 'yoel', age: 23};
WL.JSONStore.get(collectionName).add(data, options).then(function () {
// handle success
}).fail(function (error) {
// handle failure
});