Search code examples
javascriptparse-platformparse-cloud-code

How to create and save object from cloud code (parse server)


I need to create a cloud function after user registration that will create an object in path/class "publicUserInfo" with objectId same as the user's Id with given fields. I've tried to put together some code of the already answered questions here and there but I haven't seen a simple example.

My code so far:

Parse.Cloud.afterSave(Parse.User, function(request) {
console.log("Custom log -> Parse.Cloud.afterSave(Parse.User, function(request){} :");

var id = request.object.id;
var date = new Date();

var userObject = Parse.Object.extend("publicUserInfo");
var userQuery = new Parse.Query(userObject);

userQuery.equalTo("objectId", id);

userQuery.first({
        useMasterKey: true, 
        success:function(userData){
            userData.set("nick", id);
            userData.set("nickch", date);
            userData.set("avatar", "1");
            userData.set("avatarch", date);
            userData.set("points", 0);
            userData.set("state", true);
            userData.set("lastSeen", date);
            userData.save(null, { useMasterKey: true });
        },
        error: function(error){
            console.log(error);
            response.error(error);
        }
    });

});

I think the code is searching for an object first and if found it inserts the data. I might be wrong but I need it to save the data in publicUserInfo -> id same as the user's, the data is not there hence no need to be searched for, I must create it. Any ideas?


Solution

  • you cannot set the id, and you shouldn't need to. Instead, make a pointer to the user that the public user info belongs to.

    Here's my version of the code with a unit test to make sure that it works as expected. Note that I am using modern javascript. You should be using either node 8 or 10, my code will run with that.

    const makePublicUser = function makePublicUser(request) {
      // use destructuring to get request objects
      const { object: user, log } = request;
      log.info('Custom log -> Parse.Cloud.afterSave(Parse.User, function(request){} :');
      const date = new Date();
      const userQuery = new Parse.Query('publicUserInfo');
      userQuery.equalTo('user', user);
    
      // could use async/await, but will do with promises
      return userQuery.first({ useMasterKey: true }) // shouldn't need the master here
        .then((result) => {
          const userData = result || new Parse.Object('publicUserInfo', { user });
          userData.set('nick', id);
          userData.set('nickch', date);
          userData.set('avatar', '1');
          userData.set('avatarch', date);
          userData.set('points', 0);
          userData.set('state', true);
          userData.set('lastSeen', date);
          return userData.save(null, { useMasterKey: true });
        })
        .catch(log.error.bind(log));
    };
    
    describe('StackOverflow', function () {
      beforeAll(function () {
        Parse.Cloud.afterSave(Parse.User, makePublicUser);
      });
    
      it('should create a publicUserInfo', async function () {
        const user = new Parse.User({ username: 'foo', password: 'bar' });
        await user.save();
        const publicUserInfo = await new Parse.Query('publicUserInfo')
          .equalTo('user', user)
          .first();
        expect(publicUserInfo).not.toBeNull();
      });
    });