I'm trying to set up a game that allows playing with random players. The code below is supposed to create a GameMessage object for both paired players. To relate both objects as part of the same game, I've decided to save the objectId of of the game made for "firstplayer" in the field "otherside" for "secondplayer" and vice-versa. For some reason (perhaps the first save of firstplayer and secondplayer isn't done before the code attempts to retrieve the objectIds, meaning there are no objectIds to get?).
Short version: Why are the "otherside" values not saving?
Parse.Cloud.define("findpartner", function(request, response) {
var User = Parse.Object.extend("_User");
var user = new User();
var currentuser = Parse.User.current();
currentuser.set("searching", 0);
var query = new Parse.Query(User);
query.equalTo("searching", 1);
query.limit(50); //limit to at most 50 users
query.find({
success: function(objects) {
var amount = objects.length;
var indexNum = Math.floor((Math.random() * amount));
var newpartner = objects[indexNum];
if (amount > 0 && newpartner.id !=currentuser.id) {
newpartner.set("searching", 0);
var Firstplayer = Parse.Object.extend("GameMessages");
var firstplayer = new Firstplayer();
var Secondplayer = Parse.Object.extend("GameMessages");
var secondplayer = new Secondplayer();
firstplayer.set("sender", currentuser.id);
firstplayer.set("receiver", newpartner.id);
firstplayer.set("sent",0);
firstplayer.set("received",0);
firstplayer.set("receiverName", newpartner.getUsername());
secondplayer.set("sender", newpartner.id);
secondplayer.set("receiver", currentuser.id);
secondplayer.set("sent",0);
secondplayer.set("received",0);
secondplayer.set("receiverName", currentuser.getUsername());
firstplayer.save().then(function(secondplayer){ <<<
return secondplayer.save(); <<<
}).then(function(firstplayer_update) { <<<
return firstplayer.save({ otherside: secondplayer.id}); <<<
}).then(function(secondplayer_update){ <<<
return secondplayer.save({ otherside: firstplayer.id}); <<<
});
newpartner.save(null, {useMasterKey: true});
}
else {
currentuser.set("searching", 1);
}
currentuser.save();
response.success(amount);
},
error: function(error) {
alert("Error: " + error.code = " " + error.message);
}
});
});
I added arrows to show where the "otherside" is. They're not in the actual code. I do not doubt the code has mistakes though, I do not know javascript. I wrote it solely by studying the parse.com documentation.
I'm not convinced that it makes sense to create these 2 independent messages and link them together, but I won't let that stand in the way of getting this working. This isn't tested, but I've refactored your code and think you should try to glean a few things from it.
// Set this up once, outside of your function, and use it everywhere
var GameMessage = Parse.Object.extend("GameMessages");
Parse.Cloud.define("findpartner", function(request, response) {
// Code defensively, make sure this function requires a user be logged in.
if (!request.user) {
console.log("non-user called findpartner");
return response.error("Unauthorized.");
}
// Get the user who called the function
var user = request.user;
// The end response is a number, apparently
var result = 0;
// The target player
var targetPlayer;
// The two messages that will be used if a match is found
var firstmsg = new GameMessage();
var secondmsg = new GameMessage();
// Create a Users query
var query = new Parse.Query(Parse.User);
query.equalTo("searching", 1);
query.notEqualTo("objectId", user.id);
query.limit(50);
// Remove public access to Find operations for Users in the Data Browser
// Use the master key to query, and use promise syntax.
query.find({ useMasterKey: true }).then(function(objects) {
result = objects.length;
// If no users were found searching, mark the user as searching and save
if (result == 0) {
user.set('searching', 1);
// Return the save promise
return user.save(null, { useMasterKey: true });
}
// Pick a random user out of the response
var indexNum = Math.floor((Math.random() * objects.length));
var targetPlayer = objects[indexNum];
// Set that user to no longer be searching and save
targetPlayer.set("searching", 0);
return targetPlayer.save(null, { useMasterKey: true }).then(function() {
firstmsg.set("sender", user.id);
firstmsg.set("receiver", targetPlayer.id);
firstmsg.set("sent", 0);
firstmsg.set("received", 0);
firstmsg.set("receiverName", targetPlayer.getUsername());
secondmsg.set("sender", targetPlayer.id);
secondmsg.set("receiver", user.id);
secondmsg.set("sent", 0);
secondmsg.set("received", 0);
secondmsg.set("receiverName", user.getUsername());
// Return the promise result of saving both messages
return Parse.Object.saveAll([firstmsg, secondmsg], { useMasterKey: true });
}).then(function(messages) {
// Set the pointers to reference each other
firstmsg.set("otherside", secondmsg.id);
secondmsg.set("otherside", firstmsg.id);
// Return the promise result of saving both messages, again
return Parse.Object.saveAll([firstmsg, secondmsg], { useMasterKey: true });
});
}).then(function() {
// All the stuff above has finished one way or the other, now we just need to
// send back the result. 0 if no match was made.
response.success(result);
}, function(error) {
response.error(error);
});
});