I am updating our Firestore collection date fields and noticing that the dates are being written as ISO strings and not a date. What I expect to see is that a Timestamp value is stored in Firestore.
The collection document is updated with the value but the date written is an ISO String value. When using Retool, what is the correct way to write a date to Firestore so it stores a Timestamp value?
written as:
Expect to see:
Note: these are sample I pulled from our collections, not the actual dates/fields in the example above
Hi @justin How would I do that form a JavaScript query?
if I do
const doc = {
lastUpdatedAt = moment();
}
The update fails with an error in console:
DOMException: Failed to execute 'postMessage' on 'Window': ...
FYI, doesn't throw failure in trigger only in the console and doesn't seem to fire trigger at all
DOMException: Failed to execute 'postMessage' on 'Window': function(t){var e=t%10,r=1===T(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+r} could not be cloned.
at https://retool-edge.com/sandbox.171015831ecec319aab8.js:1:152790
at new Promise (<anonymous>)
at Object.trigger (https://retool-edge.com/sandbox.171015831ecec319aab8.js:1:152686)
at eval (eval at <anonymous> (https://retool-edge.com/sandbox.171015831ecec319aab8.js:1:156796), <anonymous>:35:20)
at Array.forEach (<anonymous>)
at eval (eval at <anonymous> (https://retool-edge.com/sandbox.171015831ecec319aab8.js:1:156796), <anonymous>:8:11)
Ah, I see. It looks like the date object is getting stringified when it passes through the trigger - in the local repro I tried, I had it set up to define the object in the query itself, like so:
Is there any way you can break out the lastUpdatedAt field to be defined in the query itself? By combining it with the doc object somehow? It seems like if you pass the new Date() object in the Firebase query instead of the JS query, it should work.
Yeah, I thought of that thinking the same thing was happening. Pretty hacky as I may update one of two date fields or both. So the query may not always be the same. Funny that’s twice this week JSON not having a date type bit me.
So what is the way to take a Timestamp you receive from Firestore and write it back? Do you simply write the Timestamp object back to the update query, or does it need to be converted to a date first?
Another strange thing here. So on my test record I created a Timestamp field. When I read that field and dump it to the console, it is a string, not a Timestamp object. I thought, based on your August 13th email that Timestamps should come back as an object.
Yep, agreed it's hacky - we're still trying to figure out the right way to pass these to Firebase without turning them into strings. We should definitely support this if it's coming via a JS query to - I'll talk to the team and see what we can do here.
Re: writing back - so you can write back w/ an object that has _seconds and _nanoseconds but it looks like Firebase is just making that an object. If you want it to be a timestamp field it needs to be converted to a date first.
Re: timestamp / email, you are right - we ended up reverting back to the old format (string) to maintain backwards compatibility. I know this is confusing (and we apologize ) - adding a note into our docs mentioning it today.
Sorry again about this @brettski - def not an ideal experience and we'll see what we can do to improve it.
Will there be a fix/change to update firebase with a timestamp if you pass a timestamp from a js query to a firebase query?
For example, right now, I need to pass an object from a js query to firebase, which then updates/adds a document in firebase.
Code example:
jsQuery
jsObject: {
items: {
...
timeUpdated: new Date()
...
}
timeCreated: new Date()
}
firebaseQuery value:
{{jsQuery.data}}
So this previously worked before the changes and everything that was a timestamp updated as a timestamp in firebase. With the recent changes, I had to add a workaround that was mentioned here to convert the timestamp from the jsObject in the firebaseQuery:
This workaround works for timeCreated, however, I cannot set the items object timestamps with a “new Date()” because for my application, the items object is dynamic and the size of object is unknown until the time of triggering the queries.
Any updates on this one? I have an existing date that I don’t want changed in any way. I want FireStore to continue to see it as type Timestamp. Thanks!
Hey @ben thanks for the information. Yes, I know about this workaround, the biggest issue is that is is really rare that the date is the only thing being updated, most often it is an entire object being sent to be added or updated, which gets stringified and the date is stored as a string. There is currently know way to get the date as a Date when it's part of an object.
I just thought of this (and not thought through at all), but how about an option to JSON.parse a value being used or the ability to pass it through a transformer first? I am sure there are caveats there too.
The issue is that we stringify the items passed into the additionalScope, and that even when you JSON.parse() on the other side (in this case within the Firebase query), the value does not get converted back into a Moment object (it's just trying to parse a string). Instead, we have to use Moment within the Firebase query again, to convert the string into an object again.