Parse Cloud Code: Delete All Objects After Query - javascript

Scenario
I have an app that allows users to create an account, but also allows the user's the ability to delete their account. Upon deletion of their account I have a Cloud Code function that will delete all of the "Post"s the user has made. The cloud code I am using is...
//Delete all User's posts
Parse.Cloud.define("deletePosts", function(request, response) {
var userID = request.params.userID;
var query = new Parse.Query(Parse.Post);
query.equalTo("postedByID", userID);
query.find().then(function (users) {
//What do I do HERE to delete the posts?
users.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
}, function (error) {
response.error(error);
});
});
Question
Once I have the query made for all of the user's posts, how do I then delete them? (see: //What do I do HERE?)

You could use
Parse.Object.destroyAll(users); // As per your code – what you call users here are actually posts
See: http://parseplatform.org/Parse-SDK-JS/api/classes/Parse.Object.html#methods_destroyAll
Also, consider using Parse.Cloud.afterDelete on Parse.User (if that is what you mean by "deleting account") to do cleanups such as these.
Oh, and just to be complete, you don't need the save() routine after destroyAll()

Updates in-line below below your "What do I do HERE..." comment:
NOTES:
You don't need to call the save() method, so I took that out.
This, of course, is merely a matter of personal preference, but you may want to choose a parameter name that makes a little more sense than "users", since you're really not querying users, but rather Posts (that just happen to be related to a user).
Parse.Cloud.define("deletePosts", function(request, response) {
var userID = request.params.userID;
var query = new Parse.Query(Parse.Post);
query.equalTo("postedByID", userID);
query.find().then(function (users) {
//What do I do HERE to delete the posts?
users.forEach(function(user) {
user.destroy({
success: function() {
// SUCCESS CODE HERE, IF YOU WANT
},
error: function() {
// ERROR CODE HERE, IF YOU WANT
}
});
});
}, function (error) {
response.error(error);
});
});

Related

Parse Server Cloud Code Update User

I am attempting to update a parse user field and the function stops in the middle of it:
Parse.Cloud.define("modifyAdminStatus", function(request, response) {
var userQuery = new Parse.Query(Parse.User);
var isAdmin = request.params.adminStatus;
console.log("isAdmin:" + isAdmin);
userQuery.equalTo("username", request.params.username);
userQuery.find({ useMasterKey: true,
success: function(user) {
console.log(user.length);
console.log("Got User")
console.log(user);
user.set("isAdmin", isAdmin);
console.log("Set Status");
user.save(null, {useMasterKey: true,
success: function(user) {
response.success();
},
error: function(error) {
response.error(error.message);
}
});
},
error: function(error) {
response.error(error.message);
}
});
});
I dont get any syntax errors, when i run the code i get:
1
Got User
[ ParseUser { _objCount: 2, className: '_User', id: '2vigcitsl6' } ]
in my console. However, it seems to stop the code after i attempt to set the admin status. I have tried running it using useMasterKey but that didnt do anything so maybe I'm missing something and where the useMasterKey should go?
The answer is:
query.find({
... code here
});
Returns an array, using query.first (or selecting one object from the array) instead will get one object and allow you to set things on it.
When you're trying to save the user, parse expects two parameters. The first should be an object containing any changes, and the second should be the save options.
So in your case, simply change your save to user.save (null, {useMasterKey:true, success...})
The way you have it now would create a column on Parse.User entitled useMasterKey, if permissions allow.

How to prevent current user get notified?

I'm making an app that allows user to like and comment on other user post. I'm using Parse as my backend. I'm able to notified user everytime their post liked or commented. However if current user like or comment on their own post this current user still notified. How can I prevent this?
Here is the js code that I use:
Parse.Cloud.afterSave('Likes', function(request) {
// read pointer async
request.object.get("likedPost").fetch().then(function(like){
// 'post' is the commentedPost object here
var liker = like.get('createdBy');
// proceed with the rest of your code - unchanged
var query = new Parse.Query(Parse.Installation);
query.equalTo('jooveUser', liker);
Parse.Push.send({
where: query, // Set our Installation query.
data: {
alert: message = request.user.get('username') + ' liked your post',
badge: "Increment",
sound: "facebook_pop.mp3",
t : "l",
lid : request.object.id,
pid: request.object.get('likedPostId'),
lu : request.user.get('username'),
ca : request.object.createdAt,
pf : request.user.get('profilePicture')
}
}, {
success: function() {
console.log("push sent")
},
error: function(err) {
console.log("push not sent");
}
});
});
});
If I understand the context of where this code is correctly,
I recommend checking
if request.user.get("username") != Parse.CurrentUser.get("username")
Before sending out the push notification
Where is your cloud function being called from? If you're calling it from your ios code, then before you call the cloud code function, just prelude it with something like this:
if (PFUser.currentUser?.valueForKey("userName") as! String) != (parseUser.valueForKey("userName") as! String)

Twitter authentication in Codebird JS

I am very new to integrating social sites into a website. I somewhat managed to integrate Facebook, but I have no idea how to integrate Twitter.
I want to login through a Twitter account, then get the username and some other data from Twitter. I have a consumer key and consumer secret. I'm not sure how to proceed from here, and my Google searches haven't helped so far.
I am trying with codebird js:
$(function() {
$('#twitter').click(function(e) {
e.preventDefault();
var cb = new Codebird;
cb.setConsumerKey("redacted", "redacted");
cb.__call(
"oauth_requestToken",
{ oauth_callback: "http://127.0.0.1:49479/" },
function (reply, rate, err) {
if (err) {
console.log("error response or timeout exceeded" + err.error);
}
if (reply) {
// stores it
cb.setToken(reply.oauth_token, reply.oauth_token_secret);
// gets the authorize screen URL
cb.__call(
"oauth_authorize",
{},
function (auth_url) {
window.codebird_auth = window.open(auth_url);
}
);
}
}
);
cb.__call(
"account_verifyCredentials",
{},
function(reply) {
console.log(reply);
}
);
})
});
But I get
Your credentials do not allow access to this resource
How can I resolve this and get the user data? I am open to using an alternate Twitter implementation.
You cannot call cb._call( "account_verifyCredentials"... there.
The code only has a request token, NOT an access token, which you will only receive after the user authorizes your app (on the Twitter auth popup).
You are using the "callback URL without PIN" method, as documented on the README. So you'll need to implement that example code on your http://127.0.0.1:49479/ page.
Also, this essentially requires that you store the oauth credentials somewhere. In my example below, I've used localStorage.
$(function () {
$('#twitter').click(function (e) {
e.preventDefault();
var cb = new Codebird;
cb.setConsumerKey("CeDhZjVa0d8W02gWuflPWQmmo", "YO4RI2UoinJ95sonHGnxtYt4XFtlAhIEyt89oJ8ZajClOyZhka");
var oauth_token = localStorage.getItem("oauth_token");
var oauth_token_secret = localStorage.getItem("oauth_token_secret");
if (oauth_token && oauth_token_secret) {
cb.setToken(oauth_token, oauth_token_secret);
} else {
cb.__call(
"oauth_requestToken", {
oauth_callback: "http://127.0.0.1:49479/"
},
function (reply, rate, err) {
if (err) {
console.log("error response or timeout exceeded" + err.error);
}
if (reply) {
console.log("reply", reply)
// stores it
cb.setToken(reply.oauth_token, reply.oauth_token_secret);
// save the token for the redirect (after user authorizes)
// we'll want to compare these values
localStorage.setItem("oauth_token", reply.oauth_token);
localStorage.setItem("oauth_token_secret", reply.oauth_token_secret);
// gets the authorize screen URL
cb.__call(
"oauth_authorize", {},
function (auth_url) {
console.log("auth_url", auth_url);
// JSFiddle doesn't open windows:
// window.open(auth_url);
$("#authorize").attr("href", auth_url);
// after user authorizes, user will be redirected to
// http://127.0.0.1:49479/?oauth_token=[some_token]&oauth_verifier=[some_verifier]
// then follow this section for coding that page:
// https://github.com/jublonet/codebird-js#authenticating-using-a-callback-url-without-pin
});
}
});
}
})
});
Also made a JSFiddle

Save changes to a user that is not currently logged in

In my _User class I have a column named check. The initial value of the column for someUser(some other saved user) is true and as a currentUser(currently logged in user) I want to be able to change that value to false.
Unfortunately for security reasons, Parse won't allow me to save any changes to a user that is not currently logged in, and I get an error: User cannot be saved unless they have been authenticated via logIn or signUp. I already tried adding ACL to Public read and write, but It didn't work.
I know I need to use Cloud Code and the Master Key to get it sorted out.
There is this post: Can't write non current user objects by PFUser currentuser, but I can't figure out the way to adapt it.
Parse.Cloud.define("test_func", function (request, response) {
var user = request.user;
user.increment("blabla", value); //do user stuff
user.save(); // You don't need masterkey to edit your own user object
// Get authentication to edit other user objects
Parse.Cloud.useMasterKey();
// query or get another user
var user2 = ...
user2.increment("blabla", value); // do user2 stuff
user2.save();
// Finish cloud func
response.success("yeeey");
}
If you don't useMasterKey Parse will give error while saving user2
You can use something like this:
Parse.Cloud.define("update_user", function(request, response) {
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", request.params.objectId)
// Queries user to be updated
query.first({
success: function(user) {
user.set("check", request.params.check);
// Updates user (using MasterKey to get permission to update non logged in users)
user.save(null, { useMasterKey: true }).then(function() {
response.success();
}, function(error) {
response.error(error);
});
}, error: function(error) {
response.error(error);
}
});
});
And call the "update_user" function (e.g.: in Objective-C):
NSDictionary *params = #{#"objectId" : user.objectId,
#"check" : #"true"};
[PFCloud callFunctionInBackground:#"update_user" withParameters:params block:^(id object, NSError *error) {
NSLog(#"error: %#", error.userInfo[#"error"]);
}];

AngularJS tutorial Thinkster.io chapter 7

UPDATE: The tutorial was updated and the following question really no longer applies
Learning about AngularJS from the site thinkster.io (free ebook). But at the moment i'm stuck at chapter 7 - Creating your own user data using firebase. This is an tutorial about angularjs that works with firebase.
I have wrote all the code according to the site, but i'm getting these console errors when I want to register a user. It will create the user (in firebase -simplelogin), but not the user object (in firebase - data).:
TypeError: undefined is not a function
at Object.User.create (http://localhost:9000/scripts/services/user.js:46:19)
at http://localhost:9000/scripts/controllers/auth.js:32:22
etc.
This is the code (same as the site), the error is in the create() function and talks about the users.$save() function, snippet of User.create():
users.$save(username).then(function () {
setCurrentUser(username);
});
Complete code of user.js:
news.factory("User", function ($firebase, FIREBASE_URL, $rootScope, $log) {
var reference, users, User;
reference = new Firebase(FIREBASE_URL + "users");
users = $firebase(reference);
function setCurrentUser(username) {
$rootScope.currentUser = User.findByUsername(username);
}
$rootScope.$on("$firebaseSimpleLogin:login", function (event, authUser) {
var query = $firebase(reference.startAt(authUser.uid).endAt(authUser.uid));
query.$on("loaded", function () {
setCurrentUser(query.$getIndex()[0]);
});
});
$rootScope.$on("$firebaseSimpleLogin:logout", function () {
delete $rootScope.currentUser;
});
User = {
create: function (authUser, username) {
users[username] = {
md5_hash: authUser.md5_hash,
username: username,
"$priority": authUser.uid
};
$log.debug(users);
users.$save(username).then(function () {
setCurrentUser(username);
});
},
findByUsername: function (username) {
if (username) {
return users.$child(username);
}
},
getCurrent: function () {
return $rootScope.currentUser;
},
signedIn: function () {
return $rootScope.currentUser !== undefined;
}
};
return User;
});
Edit 1:
Registering a user now works, got it working (saving in firebase, simple login and data):
users = $firebase(reference).$asObject();
Notice the users.save() function:
create: function (authUser, username) {
users[username] = {
md5_hash: authUser.md5_hash,
username: username,
$priority: authUser.uid
};
$log.debug(users);
users.$save().then(function () {
setCurrentUser(users);
});
},
findByUsername: function (users) {
if (users) {
return users;
}
},
Edit 2:
Now I get an error at the log in of the user (see below), when I want to log in, I get an error on this this function, query.$on():
TypeError: undefined is not a function
at http://localhost:9000/scripts/services/user.js:26:19
$rootScope.$on("$firebaseSimpleLogin:login", function (event, authUser) {
var query = $firebase(reference.startAt(authUser.uid).endAt(authUser.uid));
query.$on("loaded", function () {
setCurrentUser(query.$getIndex()[0]);
});
});
What is wrong now?
This is an answer on edit 2: I have used firebase(ref), query.$loaded and searched for the right object, that's it. Maybe someone have an different answer, please post them :).
I have finally completed chapter 07!
In general (solution for Edit 2):
$rootScope.$on("$firebaseSimpleLogin:login", function (event, authUser) {
var query = $firebase(reference).$asObject();
query.$loaded(function (result) {
angular.forEach(result, function (key) {
if (key.md5_hash === authUser.md5_hash) {
setCurrentUser(key);
}
});
});
});
This is not the ideal solution, but the free ebook (atm of writing) is far from ideal. Then again, these kind of situations helps you to understand a little bit more about the firebase api and how it works with angular. But can be frustrated at times, when you just want to go through the tutorial ;).
Note! I have saved the User object and pass the User object to the findUsername() and setCurrentUser() functions instead of just the user.username.
You can also use the native array function, like some().
I think your system uses the newer version of Angularfire (version>= 0.8). Which means for running through loops that are arrays ...you need to attach .$asArray() at the end of the user definition field. Check the updates of Firebase.

Categories

Resources