parse-server icon indicating copy to clipboard operation
parse-server copied to clipboard

Nested `Date` type attributes are saved differently at different levels

Open hariprasadiit opened this issue 2 years ago • 3 comments

New Issue Checklist

Issue Description

If we try to create an object with below code

const myObj = new Parse.Object('Company3');
await myObj.save({
  prop1: 'test1',
  prop2: {
    test: {
      date: new Date()
    }
  },
  prop3: {
    date: new Date()
  }
}, {useMasterKey: true});

This is how the saved object in mongo DB looks like

{
  "_id": "5DTIqZcZv9fhbHu0qTZq",
  "prop2": {
    "test": {
      "date": {
        "__type": "Date",
        "iso": "2021-09-14T14:50:37.303Z"
      }
    }
  },
  "prop3": {
    "date": {
      "$date": "2021-09-14T14:50:37.303Z"
    }
  },
  "prop1": "test1",
  "_created_at": {
    "$date": "2021-09-14T14:50:38.108Z"
  },
  "_updated_at": {
    "$date": "2021-09-14T14:50:38.108Z"
  }
}

prop2.test.date is saved as JSON object instead of $date object while prop3.date is properly saved. This breaks date queries

Steps to reproduce

  1. Create new object with below code
const myObj = new Parse.Object('Company3');
await myObj.save({
  prop1: 'test1',
  prop2: {
    test: {
      date: new Date()
    }
  },
  prop3: {
    date: new Date()
  }
}, {useMasterKey: true});
  1. Observe different date types at different levels in mongoDB Compass

Actual Outcome

{
  "_id": "5DTIqZcZv9fhbHu0qTZq",
  "prop2": {
    "test": {
      "date": {
        "__type": "Date",
        "iso": "2021-09-14T14:50:37.303Z"
      }
    }
  },
  "prop3": {
    "date": {
      "$date": "2021-09-14T14:50:37.303Z"
    }
  },
  "prop1": "test1",
  "_created_at": {
    "$date": "2021-09-14T14:50:38.108Z"
  },
  "_updated_at": {
    "$date": "2021-09-14T14:50:38.108Z"
  }
}

Expected Outcome

{
  "_id": "5DTIqZcZv9fhbHu0qTZq",
  "prop2": {
    "test": {
      "date": {
        "$date": "2021-09-14T14:50:37.303Z"
      }
    }
  },
  "prop3": {
    "date": {
      "$date": "2021-09-14T14:50:37.303Z"
    }
  },
  "prop1": "test1",
  "_created_at": {
    "$date": "2021-09-14T14:50:38.108Z"
  },
  "_updated_at": {
    "$date": "2021-09-14T14:50:38.108Z"
  }
}

Environment

Server

  • Parse Server version: 4.10.3
  • Operating system: Mac OS
  • Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc): Local

Database

  • System (MongoDB or Postgres): MongoDB
  • Database version: 4.4.4
  • Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc): Local

Client

  • SDK (iOS, Android, JavaScript, PHP, Unity, etc): Javascript
  • SDK version: 3.3.0

Old issue related to this #6840

hariprasadiit avatar Sep 14 '21 15:09 hariprasadiit

Thanks for opening this issue!

  • 🚀 You can help us to fix this issue faster by opening a pull request with a failing test. See our Contribution Guide for how to make a pull request, or read our New Contributor's Guide if this is your first time contributing.

I was able to reproduce the issue. Would you want to open a PR with a failing test?

I classified this as bug with severity S3 (normal):

  • Workaround is to use a different data structure in the object that does not nest date fields deeper than 1 level

mtrezza avatar Sep 14 '21 20:09 mtrezza

I suspect this is more of a JS SDK issue. According to the REST documentation, Parse treats Date as a special data type:

The Date type contains a field iso which contains a UTC timestamp stored in ISO 8601 format with millisecond precision: YYYY-MM-DDTHH:MM:SS.MMMZ.

{
  "__type": "Date",
  "iso": "2022-01-01T12:23:45.678Z"
}

So the outcome of prop2 looks correct IMO and the others are wrong:

"prop2": {
    "test": {
      "date": {
        "__type": "Date",
        "iso": "2021-09-14T14:50:37.303Z"
      }
    }
  }

My explanation https://github.com/parse-community/parse-server/issues/8001#issuecomment-1133631026 may provide some more context on what the JS SDK should be doing. From your current post it seems the JS SDK is partially encoding date correctly, but not handling date correctly on top level dates (i.e. prop3)

I suspect the issue is here in the JS SDK: https://github.com/parse-community/Parse-SDK-JS/blob/e2bd6be145f55fab322633a8f144be34e7fcb202/src/encode.js#L62-L67. If you add an if statement to check if the current top level object is a date and use a similar block transforming the date to the iso format, it should fix this issue.

cbaker6 avatar May 21 '22 13:05 cbaker6

🎉 This change has been released in version 6.0.0-alpha.15

parseplatformorg avatar Dec 20 '22 15:12 parseplatformorg

🎉 This change has been released in version 6.0.0-beta.1

parseplatformorg avatar Jan 31 '23 03:01 parseplatformorg

🎉 This change has been released in version 6.0.0

parseplatformorg avatar Jan 31 '23 03:01 parseplatformorg