I'm trying to make a cloud function which saves the sender's objectId and username as an array, inside the array "request", for the target and have the target's objectId and username saved as an array, in the array "pending" for the sender.
Parse.Cloud.define("newGameRequest", function(request, response) {//A
// Get the user who called the function
var user = request.user;
var target;
var query = new Parse.Query(Parse.User);
query.get(request.params.friendId, {
success: function(object) {
var target = object;
var friendInfo = [target.objectId, target.username];
var userInfo = [user.objectId, user.username];
user.add("pending",friendInfo);
target.add("request",userInfo);
Parse.Object.saveAll([user, target], { useMasterKey: true });
response.success("Success");
},
error: function(object, error) {
response.error(error);
}
});
});
Looking in the data browser shows that the arrays for each respective user were saved, but saved with null values only ([[null,null]] for both).
The call is from an iOS device and is the following:
[PFCloud callFunctionInBackground:#"newGameRequest"
withParameters:#{#"friendId": self.friend.objectId}
block:^(NSString *result, NSError *error) {
if (!error) {
}
else {
NSLog(#"%#",result);
}
}];
self.friend.objectId has been tested and is the right result.
What is the issue with my cloud code?
I'm an idiot.
getting the object Id of user is the like the following:
user.id
and getting the username is done like this:
user.getUsername()
Related
I have this helper:
agreed: function (){
if (Meteor.users.findOne({_id: Meteor.userId(), profile: {agreedTermsOfUse: 'true'}}))
return true;
}
On the page where I check it I have this:
{{#unless agreed}}
agree form
{{else}}
Create item form.
{{list of item}}
{{/unless}}
So far, all goes well. The user signs up then he can create an item and it renders on the list of items..
Now, I've added another Meteor.call, which when getting the success call back on the client, for the creating item, it adds the item id to the users' profile.hasItems.
Then after getting succes for that method, "unless" returns false, and I have to submit the agree to form again.
What am I missing? Thanks.
"submit .create_restaurant": function (event) {
event.preventDefault();
var text = event.target.create_restaurant.value;
Meteor.call('CreateRest', Meteor.userId(), text, function(error, result){
if(error){
}else{
console.log(result, Meteor.userId());
Meteor.call('userRestaurants', result, Meteor.userId(), function (error, result) {
if (error) {
alert(123);
} else {
console.log(result);
}
})
}
}
);
event.target.create_restaurant.value = "";
}
methods:
'CreateRest': function(user_id, title) {
check(title, String);
check(user_id, String);
return callback = Restaurants.insert({
createdBy: user_id,
createdAt: new Date(),
title: title
});
},
'userRestaurants': function(rest_id, createdBy) {
var restId = checkHelper(rest_id, createdBy);
if(restId)
console.log(rest_id, createdBy);
{
var callback = Meteor.users.update(
createdBy,
{$addToSet: {'profile.hasRestaurants': restId}}
);
return callback;
}
}
I don't know why you're seeing the behaviour that you are, but I do know that you have other problems to sort out first :)
You have a huge security hole - you're passing the user id through to the method from the client. That means that anyone can simply open the browser console and create a restaurant with any user id they like as the owner. Instead, use this.userId in the method to get the id of the caller.
Why the round trip to the server? Just have the first method update the client.
So, something like this (untested, written by hand here):
"submit .create_restaurant": function (event) {
event.preventDefault();
var text = event.target.create_restaurant.value;
Meteor.call('CreateRest',text, function(error, result){
if(error){
alert(123);
}else{
console.log(result);
}
});
event.target.create_restaurant.value = "";
}
and:
'CreateRest': function(user_id, title) {
check(title, String);
check(this.userId, String);
userId = this.userId;
Restaurants.insert({
createdBy: userId,
createdAt: new Date(),
title: title
}, function(err, restId) {
if (err) throw new Meteor.Error(err);
Meteor.users.update(
userId,
{$addToSet: {'profile.hasRestaurants': restId}},
function (err, res) {
if (err) throw new Meteor.Error(err);
return restId;
}
);
});
Once that's implemented properly it might start working. If it doesn't then the issue isn't related to the code you're posting.
Finally note that from a schema perspective it's really odd that that you have profile.hasRestaurants. To find the restaurants that a user has you should just do a find on the Restaurants collection.
I am attempting to link a School class with a list of users (a School can have many Users, and a User belongs to a School). Per several suggestions, I am using Parse's Cloud Code and Master key to accomplish this.
My issue is that, instead of passing a string parameter or another User, I am linking a School object to the user.
Here is my Cloud Code, which is causing an error when ran and no changes made to Parse's backend:
Parse.Cloud.define('addNewSchoolRelation', function(request, response) {
var userId = request.params.userId,
associatedSchoolObject = request.params.associatedSchoolObject;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
var relation = user.relation("schoolRelation");
relation.set(associatedSchoolObject);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
And inside my app, this is how I call it:
PFQuery *schoolQuery = [PFQuery queryWithClassName:#"School"];
[schoolQuery whereKey:#"objectId" equalTo:#"FgpHfOGIdC"]; //this is the test one
[schoolQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error %#", error);
} else {
PFObject *school = [objects firstObject];
[PFCloud callFunctionInBackground:#"addNewSchoolRelation" withParameters:
#{#"userId": #"BHqvZ6PrLl", //testing for now
#"associatedSchoolObject": school,
} //sets that user's newChats
block:^(id object, NSError *error) {
if (error){
NSLog(#"Error %#", error);
} else {
NSLog(#"Saved on remote user");
}
}];
}
}];
I'm pretty sure culprit is in my Javascript code - am I passing the parameter incorrectly? I'm not sure what I'm doing incorrectly and any help is much appreciated, thanks!
I am implementing the tutorial on the mean stack https://www.youtube.com/watch?v=AEE7DY2AYvI
I am adding a delete feature to remove items from the database on a button click
My client side controller has the following 2 functions to add to db and remove
$scope.createMeetup = function() {
var meetup = new Meetup();
meetup.name = $scope.meetupName;
meetup.$save(function (result) {
$scope.meetups.push(result);
$scope.meetupName = '';
});
}
$scope.deleteMeetup = function() {
item = $scope.meetups[0];
console.log("deleting meetup: " + item["name"]);
Meetup.delete(item);
scope.meetups.shift();
}
My server side has the following code
module.exports.create = function (req, res) {
var meetup = new Meetup(req.body);
meetup.save(function (err, result) {
res.json(result);
});
}
module.exports.remove = function(req, res) {
console.log("GOING TO REMOVE!!!");
console.log(req.query);
item = req.query;
Meetup.remove(item, function (err, results) {
console.log("done");
console.log(err);
console.log(results);
});
}
When I run my code and if I delete an already loaded item in the list, it is removed from Mongodb just fine. But if I add an item to the list and I do not refresh the page, it results in an error at my server that appears as
GOING TO REMOVE!!!
{ '$resolved': 'true',
__v: '0',
_id: '54ec04e70398fab504085178',
name: 'j' }
done
{ [MongoError: unknown top level operator: $resolved]
name: 'MongoError',
code: 2,
err: 'unknown top level operator: $resolved' }
null
I if I refresh the page, the it gets deleted fine. But if I added the entry, angular seems to be adding a new variable $resolved. Why is that happening?
Also another question, What is the proper way to call delete? I call it now but I am not able to put a callback. I want a callback which returns and then I shift the list of items. I tried adding a callback but the code never reaches it.
ie I tried the following
/*
Meetup.delete(item, function () {
console.log("In callback!!");
console.log(returnValue);
console.log(responseHeaders);
$scope.meetups.splice(item);
});
*/
/*Meetup.delete(item,
function (returnValue, responseHeaders) {
console.log("In callback!!");
console.log(returnValue);
console.log(responseHeaders);
$scope.meetups.splice(item);
},
function (httpResponse){
// error handling here
console.log("Need to handle errors");
});
*/
I am very new to node and am confused. Any help is very, very appreciated
Looks like it possible to call item.delete instead of Meetup.delete(item). You can call same methods on model instance. It prevent sending angular properties to server.
But better to make a rest API with delete method
DELETE /meetups/:id
and send just a _id
Meetup.remove({id: item._id});
I want to send a push notification from parse cloud code to a specific user.
So i have created a user section in installation class of my parse table and i save the user object id there so i can target the user by id and send push from cloud code.
https://www.dropbox.com/s/dvedyza4bz3z00j/userObjec.PNG?dl=0
From parse.com it is very simple to do, i did it like this with condition
https://www.dropbox.com/s/1mb3pb2izb0jlj9/pushs.PNG?dl=0
But what i want to do is to send a push notification when a user adds new object in the class my class is "Ticket".
This class has ACL enabled.
What i want to do is very simple send push to the user which created the object through cloud code
Here is my cloud code
Parse.Cloud.afterSave("Ticket", function(request) {
var pushQuery = new Parse.Query(Parse.Installation);
Parse.Push.send({
where: pushQuery,
data: {
alert: "New Ticket Added",
sound: "default"
}
},{
success: function(){
response.success('true');
},
error: function (error) {
response.error(error);
}
});
});
This code sends push to all users.
Please help
This can be a solution:
Parse.Cloud.afterSave( "Ticket", function(request) {
//Get value from Ticket Object
var username = request.object.get("username");
//Set push query
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("username",username);
//Send Push message
Parse.Push.send({
where: pushQuery,
data: {
alert: "New Ticket Added",
sound: "default"
}
},{
success: function(){
response.success('true');
},
error: function (error) {
response.error(error);
}
});
});
You have to add a filter to the pushQuery for the user created the object.
Scenario
I have these two Cloud Functions that I want to use in my application. They check for the online status of the user and I want to set a boolean key "isOnline" for each user to YES if the user is online and to NO if they are not.
var moment = require("moment");
Parse.Cloud.define("registerActivity", function(request, response) {
var user = request.user;
user.set("lastActive", new Date());
user.save().then(function (user) {
response.success();
}, function (error) {
console.log(error);
response.error(error);
});
});
Parse.Cloud.define("getOnlineUsers", function(request, response) {
var userQuery = new Parse.Query(Parse.User);
var activeSince = moment().subtract("minutes", 2).toDate();
userQuery.greaterThan("lastActive", activeSince);
userQuery.find().then(function (users) {
response.success(users);
}, function (error) {
response.error(error);
});
});
Problem
I am not the best with Javascript, and because of that I need some help getting my head around what is happening/what I'm supposed to do.
Questions
1) When do I call "registerActivity" and "getOnlineUsers" inside my Xcode project?
2) Is "response.success(users)" just an array of PFUser Objects?
3) If "2)" is true, then how do I set the bool key "isOnline" for all of the users in the "response.success(users)" to YES if they are in the array?
You would call these functions when you want to get the online users. The code for calling these would be:
[PFCloud callFunctionInBackground:#"registerActivity" withParameters:#{#"user": Put objectId for user here}
block:^(NSString *response, NSError *error) {
if (!error) {
}
}];
[PFCloud callFunctionInBackground:#"getOnlineUsers" withParameters:#{}
block:^(NSArray *users, NSError *error) {
if (!error)
{
} }];
Yes, I believe it would just be an array of PFUser objects, I would run this just to make sure, though.
Once you get the response from "getOnlineUsers" you should probably send it back up to another cloud code function that uses the master key (Parse.Cloud.useMasterKey();) to access/change user objects, and change the "isOnline" field to YES.