I'm developing an iOS app with Parse SDK hosted on back4app, my app in the back4app dashboard hosts a main.js file in Cloud Code that sends push notifications, it gets called by code and it works fine.
Now I've added a blockuser.js file in my Cloud Code, such file should edit the isBlocked column (of type Boolean) of a specific user in _User class and set it to true, here's the code I use:
Parse.Cloud.define("blockUser", function(request, response) {
var userId = request.params.userId,
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.set('isBlocked', true);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
Here's the Swift code I wrote to call that function:
let request = ["userId" : userPointer.objectId!] as [String : Any]
PFCloud.callFunction(inBackground: "blockUser", withParameters: request as [String : Any], block: { (results, error) in
if error == nil {
print ("\(userPointer["username"]!) has been blocked!")
// error in cloud code
} else {
print ("\(error!.localizedDescription)")
}})
The Xcode console prints out this message:
[Error]: Invalid function. (Code: 141, Version: 1.14.2)
In fact, that blockUser function doesn't work at all.
Anybody knows what I'm doing wrong in the .js or swift code?
After a few attempts, I've figured it out, here's the function I've added in my main.js file in Cloud Code:
// BLOCK A USER ----------------------------------------
Parse.Cloud.define("blockUser", function(request, response) {
var userId = request.params.userId;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.set('isBlocked', true);
Parse.Cloud.useMasterKey();
user.save(null, { useMasterKey: true } ).then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
And here's the Swift 3 code to call blockUser function:
let request = [
"userId" : userPointer.objectId!
] as [String : Any]
PFCloud.callFunction(inBackground: "blockUser", withParameters: request as [String : Any], block: { (results, error) in
if error == nil {
print ("\(userPointer["username"]!) has been blocked!")
// error
} else {
print ("\(error!.localizedDescription)")
}})
it seems like you did not reload your main.js (file where you write cloud code functions) on server
Related
I am trying to use hapi-auth-bearer-simple module to enable bearer token on my app. However, I am getting the error shown in the title.
I am trying to implement this module to enable token authorisation in my app But I am getting error mentioned below
e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\node_modules\hoek\lib\index.js:723
I have a route file
module.exports = [
{
method: 'GET',
path: '/api/{_id?}',
handler: function (request, reply) {
Controller.control.get(request.params, function (err, success) {
console.log(request.params);
if (err) {
reply(unifunc.sendError(err));
} else {
reply(unifunc.sendSuccess(SuccessMsg,success)).code(200);
}
});
},
config: {
description: 'desc',
tags: ['api', 'oV'],
validate: {
headers: unifunc.authorizationHeaderObj,
params: {
o_id: Joi.string().required().trim(),
_id: Joi.string().optional().trim()
},
failAction: unifunc.failActionFunction
},
auth: {
strategy: 'bearer',
scope: ['admin', 'user-{params.id}']
},
plugins: {
'hapi-swagger': {
responseMessages: msgs
}](url)
and a controller file in which I mentioned strategy
var bearerSimple= require('hapi-auth-bearer-simple')
authorization = Authorization.auth; // This plugin has the logic to validate the token and return the error in case it fails and I am passing accesstoken as parameter in a function in that file
var getV = function(server, params, callbackRoute){
server.register(
[{
register: bearerSimple
}], function(err){
if(err){
console.log("Failed to log the plugin",err);
throw err;
}
server.auth.strategy('bearer', 'bearerAuth', {
authorization : authorization
});
});
console.log(params);
async.series([
function(cb){}
]}
complete error message is:
Error: Unknown authentication strategy: bearer in path: /api/orders/{order_id}/vehicles/{_id?}
at Object.exports.assert (e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\node_modules\hoek\lib\index.js:723:11)
at e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\lib\auth.js:152:14
at Array.forEach (native)
at internals.Auth._setupRoute (e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\lib\auth.js:149:24)
at new module.exports.internals.Route (e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\lib\route.js:142:47)
at internals.Connection._addRoute (e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\lib\connection.js:375:17)
at internals.Connection._route (e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\lib\connection.js:367:18)
at wrappedRoute [as _route] (e:\python_training\Training\Node\Test\Project\Backend\node_modules\newrelic\lib\instrumentation\hapi.js:222:29)
at internals.Plugin._apply (e:\python_training\Training\Node\Test\Project\Backend\node_modules\hapi\lib\plugin.js:460:14)
at internals.Plugin.route
Is there any way I can resolve this issue?
Edit:
I modified server.js file and removed the strategy from controller file
I placed strategy in server.js
var validationFunction = Authorization.auth;
console.log(validationFunction);
server.register(
[{
register: bearerSimple
}], function(err){
if(err){
console.log("Failed to log the plugin",err);
throw err;
}
server.auth.strategy('bearer', 'bearerAuth', {
validationFunction : validationFunction
});
});
and in Authorization file looks like this
function rauth(accessToken, cb) {
var criteria = {accessToken: accessToken};
var projection = {};
var options = {limit: 1};
Service.AdminService.getadmin(criteria, projection, options, function (err, data) {
if (err) {
cb(err);
} else if (data && data.length > 0 && data[0]._id) {
console.log(data);
console.log(data.length);
adminId = data[0]._id;
cb()
} else {
cb(UniversalFunctions.CONFIG.APP_CONSTANTS.STATUS_MSG.ERROR.INVALID_ACCESS_TOKEN);
}
});
Now I am getting this error:
Error: options.validateFunc must be a valid function in bearerAuthentication scheme
I have been breaking my head over this problem from days. Could anyone suggest what could be the problem here?
The only problem I found was with the parameters of callback function passed in validateFunction but I can't remove the parameters as those parameters are being defined in another function called getadmin. Could anyone suggest a workaround for this?
Solved in this issue https://github.com/Salesflare/hapi-auth-bearer-simple/issues/69.
The problems were a typo and needed to pass more info back on a successful authorization.
I'm doing my app users management with the Cognito AmazonWebService and on AngularJS.
I can not figure out how to solve this problem :
After registering, users are receiving an email with a code to confirm it. When I try to enter and validate the code I have a pop-up message saying "Error: the user is not authenticated".
But if is I swap the steps I can not authenticated myself because I've this error: "Your account must be confirmed".
EDIT: That's how I'm confirming the registration :
var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(_poolData);
var userData = {
Username : username,
Pool : userPool
};
var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.getAttributeVerificationCode('email', {
onSuccess: function (result) {
console.log('call result: ' + result);
},
onFailure: function(err) {
console.log("error");
alert(err);
},
inputVerificationCode: function(code) {
var verificationCode = prompt('Check you email for a verification code and enter it here: ' ,'');
cognitoUser.verifyAttribute('email', verificationCode, this);
}
});
I have also try this code below :
var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.confirmRegistration('123456', true, function(err, result) {
if (err) {
alert(err);
return;
}
console.log('call result: ' + result);
});
But everytime I'm using the code you gave me to confirm an user I have this error message : "ExpiredCodeException: Invalid code provided, please request a code again." while user is well confirmed in my user pool...
How could I solve it ?
Your second code is the right one to be called. How long are you waiting to call?
I am having trouble getting quickblox chat working on phonegap (javascript).I have used the revealing module pattern to expose instead of 'require' and this is the broken piece of code:
var chatParams = {
onConnectFailed: onConnectFailed,
onConnectSuccess: onConnectSuccess,
onConnectClosed: onConnectClosed,
onChatMessage: onChatMessage
};
QB.createSession(params, function(err, result) {
if (err==null) {
chatUser = {
id: result.user_id,
pass: params.password
};
connectChat(chatParams);
}
else {
alert("Something went wrong, please try again later or contact us at contact#domain.co.uk if the problem persists.");
}
});
function connectChat(chatParams) {
//This line here:
var chatService = new QBChat(chatParams);
console.log(chatService);
// connect to QB chat service
chatService.connect(chatUser);
};
I am getting the error 'object not a reference' at the highlighted line.
Please advise!
Try to use this code as an example to join chat:
QB.chat.connect({userId: user.id, password: user.pass}, function(err, roster) {
if (err) {
console.log(err);
} else {
console.log(roster);
}
});
instead of
function connectChat(chatParams) {
//This line here:
var chatService = new QBChat(chatParams);
console.log(chatService);
// connect to QB chat service
chatService.connect(chatUser);
};
I am trying to implement push notifications for my app using nodejs for the backend using quickblox. I'm following the steps to do that as mentioned on the quickblox site, i.e create a session user, create a push token, and last subscribe to notification channel. I'm facing a problem with the creation of the push token. My server side code looks like this:
app.post('/test_quickblox', function(req, res) {
var params = {
login: req.user.qb_username,
password: req.user.qb_password,
}
console.log(params);
QB.createSession(params, function(err, result) {
if (err) {
console.log(err);
}
console.log(result);
var options = {};
options.headers = {};
options.headers['QuickBlox-REST-API-Version'] = '0.1.0';
options.headers['QB-Token'] = result.token;
options.body = {};
options.body['push_token'] = {};
options.body['push_token']['environment'] = 'development';
options.body['push_token']['client_identification_sequence'] = '54b1e2b9e9081ed60520824054b1e2b8e9081ed60520823f';
options.body['device'] = {};
options.body['device']['platform'] = 'ios';
options.body['device']['udid'] = 'e0101010d38bde8e6740011221af335301010333';
options.url = 'http://api.quickblox.com/push_tokens.json';
QuickbloxRequest(options, function(err, response) {
if (err) {
console.log(err);
return apiError();
}
console.log(response);
res.apiSuccess();
});
});
});
when logging the response it looks like the following
{ _id: '54b1e3a1535c121c2000be66',
application_id: 18113,
created_at: '2015-01-11T02:44:49Z',
device_id: 0,
nonce: 8394,
token: 'bf61098a35fac9389be236caec44f0a9827630d1',
ts: 1420944288,
updated_at: '2015-01-11T02:44:49Z',
user_id: 2179940,
id: 56046 }
and the error I get is:
{"code":null,"message":"No device registered for current user session. Device is obligatory to be able to execute actions with push token."}
I guess the problem lies in the device_id being 0.
Note that I am creating the users in another controller without supplying any device_id upon creation, so I think that might be my problem but I am new to quickblox and do not understand yet all the semantics so please help me find out what the problem is. Thanks
And here we are 4 years later and I faced the same problem. No answer, no nothing, it makes you wonder how large is the quickblox community :O
Anyway, for anyone coming here with the same problem : It seems the problem is that the Android UUID returned by PhoneGap is too short so quickblox rejects it silently.
Here is what worked for me. Pay attention to the doubling of the uuid :
window.device.uuid + window.device.uuid
JS Code :
//REGISTER AS ANDROID
var message = {
environment: "development",
client_identification_sequence: e.regid,
platform: "android",
udid: window.device.uuid + window.device.uuid,
};
if (BBPushNotification.showLog) console.log(message);
QB.messages.tokens.create(message, function(err, response){
if (err) {
if (BBPushNotification.showLog) console.log("Create token error : ",err);
} else {
if (BBPushNotification.showLog) console.log("Create token success : ",response);
}
});
I am confused on how to update a user from cloud code. If someone can help me out with getting my mind right about this I'd appreciate it.
The cloud code I will use for this example is:
cloud code
Parse.Cloud.define("like", function(request, response) {
var userID = request.params.userID;
var User = Parse.User();
user = new User ({ objectId: userID });
user.increment("likes");
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
called from iOS
[PFCloud callFunctionInBackground:#"like" withParameters:#{#"userID": self.selectedFriendID} block:^(id object, NSError *error) {
}];
Questions
user = new User ({ objectId: userID });
1) is the "new" in the code above creating a "brand new" user, or is it "grabbing" an existing user at the objectId so that it can be updated on user.save?
2) if the latter is correct, than is it possible to "grab" a user from a column other than the objectId column, and maybe instead grab from the userID column?
eg:
user = new User ({ userID : userID });
This line:
user = new User ({ objectId: userID });
Creates an instance of an object with a known ID, it only works with objectId. Any changes you make to that object are persisted, but no other data is changed (e.g. you won't accidentally blank out the other columns).
If instead you wanted to get a user by email you would have to do a query:
var userQuery = new Parse.Query(Parse.User);
userQuery.equalTo('email', userEmail);
userQuery.first().then(function(user) {
if (user) {
// do something with the user here
user.set('new_col', 'new text');
user.save().then(function() {
response.success();
});
} else {
// no match found, handle it or do response.error();
}
});
// the above code is async, don't put anything out here and expect it to work!
What I would do to retrieve the user in cloud code is query.get(request.params.userID.... I believe this returns the user object. I do not know if you can do this with other columns. There is lots of stuff in the cloud code docs about this, though. Here is my cloud code function for editing a user, if that helps:
Parse.Cloud.define("editUser", function(request, response) {
//var GameScore = Parse.Object.extend("SchoolHappening");
// Create a new instance of that class.
//var gameScore = new GameScore();
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.get(request.params.myUser, {
success: function(myUser) {
// The object was retrieved successfully.
myUser.set("cabinetPosition", request.params.myPosition);
// Save the user.
myUser.save(null, {
success: function(myUser) {
// The user was saved successfully.
response.success("Successfully updated user.");
},
error: function(gameScore, error) {
// The save failed.
// error is a Parse.Error with an error code and description.
response.error("Could not save changes to user.");
}
});
},
error: function(object, error) {
// The object was not retrieved successfully.
// error is a Parse.Error with an error code and description.
}
});
});