Cloud Code object.save() 使用非常奇怪的 PUT 命令导致 'object not found'

Cloud Code object.save() results in 'object not found' with very strange PUT command

问题描述

我有一个简单的云代码命令来创建或更新对象。如果没有传入 objectId,例程将创建一个新对象和 returns objectId。如果参数列表中存在objectId,则获取对象并相应地更新参数。

例程适用于新对象。

当我尝试更新对象时,object.save() 失败了,尽管 object.fetch() 子例程在工作。

error: code=101, message=Object not found.

详细的服务器日志表明一个非常奇怪的 PUT 命令...

PUT /parse/classes/Receipt/[object%20Object]

我希望看到的是

PUT /parse/classes/Receipt/GJaXcf7fLD

对象 ACL 是 public r+w

为什么 object.save() 不能使用有效的 objectId?

_

云码

Parse.Cloud.define("uploadReceipt", function(request,response) {
    var Receipt = Parse.Object.extend("Receipt");
    var receipt = new Receipt();

    // passed in parameters are ['property' : ['type' : t, 'value' : v]]
    var dict = request.params;
    var objectIdDict = dict["objectId"];
    console.log("Object Dict: " + objectIdDict);
    Parse.Promise.as().then(function() {
        // if we already have an objectId we are UPDATING
        // Need to FETCH first
        if (objectIdDict != undefined) {
            console.log("Searching for ID: " + objectIdDict["value"]);
            receipt.set("objectId",objectIdDict["value"]);
            return receipt.fetch();
        }
        else {
            console.log("NEW RECEIPT");
            return Parse.Promise.as(receipt);
        }

    }).then(function(receipt) {
        console.log("Receipt: " + receipt.id);
        // copy over the keys from our passed in parameters to the object
        for (var key in dict) {
            //console.log("Key: " + key + "   Value: " + dict[key]["value"]);
            if (dict[key]["type"] == "Raw") {
                console.log("Key: " + key + "   Value: " + dict[key]["value"]);
                receipt.set(key,dict[key]["value"]);
            }
            else if (dict[key]["type"] == "Date" && key != "updatedAt") {
                console.log("Key: " + key + "   Value: " + dict[key]["value"]);
                var time = dict[key]["value"] * 1000;   // milliseconds
                receipt.set(key,new Date(time));
            }
            else {
                // object type
                var Obj = Parse.Object.extend(dict[key]["type"]);
                var newObj = new Obj();
                newObj.id = dict[key]["value"];
                receipt.set(key,newObj);
            }
        }

        // make sure our user is set
        receipt.set("user",request.user);

        // adjust the status because it has now been uploaded
        receipt.set("status",RECEIPT_SUBMITTED);

        console.log("Prior to save");
        return receipt.save();

    }).then(function(receipt) {
        console.log("Finished");
        response.success({"status":receipt.get("status"),"objectId":receipt.id});

    },function (error) {
        console.log(error);
        response.error(error);
    });
});

重现步骤

  1. 使用新对象的数据从 iOS SDK 调用云代码
  2. 请注意该命令有效并且一个新对象已添加到数据库
  3. 使用更新后的信息再次调用命令
  4. 请注意该命令失败并显示 未找到对象

预期结果

对象应相应更新

实际结果

error: code=101, message=Object not found.

环境设置

Logs/Trace

存储新对象returns

verbose: POST /parse/classes/Receipt { 'user-agent': 'node-XMLHttpRequest, Parse/js1.8.5 (NodeJS 5.10.1)',
  accept: '*/*',
  'content-type': 'text/plain',
  host: 'localhost:1337',
  'content-length': '471',
  connection: 'close' } {
  "date": {
    "__type": "Date",
    "iso": "2016-06-19T00:30:37.492Z"
  },
  "category": {
    "__type": "Pointer",
    "className": "Category",
    "objectId": "XZ1bSHtZBY"
  },
  "status": 0,
  "amount": 61.45,
  "notes": "Hopefully this works well",
  "gui_status": -1,
  "currency": "USD",
  "user": {
    "__type": "Pointer",
    "className": "_User",
    "objectId": "vL4ih9BAX8"
  }
}
verbose: {
  "status": 201,
  "response": {
    "objectId": "GJaXcf7fLD",
    "createdAt": "2016-06-19T00:30:57.092Z"
  },
  "location": "http://localhost:1337/parse/classes/Receipt/GJaXcf7fLD"
}
Finished
verbose: {
  "response": {
    "result": {
      "status": 0,
      "objectId": "GJaXcf7fLD"
    }
  }
}

尝试更新对象returns

verbose: PUT /parse/classes/Receipt/[object%20Object] { 'user-agent': 'node-XMLHttpRequest, Parse/js1.8.5 (NodeJS 5.10.1)',
  accept: '*/*',
  'content-type': 'text/plain',
  host: 'localhost:1337',
  'content-length': '473',
  connection: 'close' } {
  "category": {
    "__type": "Pointer",
    "className": "Category",
    "objectId": "XZ1bSHtZBY"
  },
  "status": 0,
  "amount": 5.47,
  "notes": "How about now",
  "gui_status": 0,
  "date": {
    "__type": "Date",
    "iso": "2016-06-19T00:12:25.788Z"
  },
  "currency": "USD",
  "user": {
    "__type": "Pointer",
    "className": "_User",
    "objectId": "vL4ih9BAX8"
  }
}
verbose: error: code=101, message=Object not found.
ParseError { code: 101, message: 'Object not found.' }
verbose: error: code=141, code=101, message=Object not found.

在解析服务器社区和 GitHub 用户 flovilmart

的帮助下解决了这个问题

在 'updating' 个对象的情况下,我在收据中包含了一个字典条目。这已成功检索到我要更新的收据。

但是,问题是一旦我拉入收据对象并遍历我的属性字典以更新...我再次 运行 进入收据对象信息。因此,我试图将 属性 的收据指针添加到我的收据中,指针本身就是收据!呃.

最后一个 else 子句需要一个条件来不包含指向收据(本身)的指针

  for (var key in dict) {
    if 
    ....
    else if (dict[key]["type"] != "Receipt"){
      // object type, but don't include ourself!  (the Receipt)
      var Obj = Parse.Object.extend(dict[key]["type"]);
      var newObj = new Obj();
      newObj.set("objectId",dict[key]["value"]);
      receipt.set(key,newObj);
    }
  }