Problem with Firestore Timestamp and Google Cloud Functions (date.toDate() is not a function)

Viewed 326

I am getting a date (from firestore) in a cloud function, and then returning it to the client side.

This is the resulted date object:

Object {
   "_nanoseconds": 1607618708,
   "_seconds": 615000000,
} // I know how to convert this to a javascript date object, but I need the .toDate()

Then, in the frontend, if I execute date.toDate() I get the error ".toDate is not a function".

In the other hand, if I get the same date from the client directly, all works perfectly... (.toDate() is a function)

This is the resulted date object:

t {
    "nanoseconds": 1607618708,
    "seconds": 615000000,
}

What is happening here? How can I solve this problem?

UPDATE

-> Code which doesn't work:

// Cloud Function
var userData = await firebase.getUserData(userId); // userRef.get().then(doc => ... return doc.data());
console.log(userData.birthday);
/*
    Timestamp {
       _seconds: 1038832012,
       _nanoseconds: 14000000 
    }
*/


return { userData }

// Client side

firebase.functions.httpsCallable(...)(...).then(res => {
    console.log(res.data.userData.birthday);
    /*
        Object {
           "_nanoseconds": 1607618708,
           "_seconds": 615000000,
        }

        new Date(date._seconds * 1000) will work but I need to execute .toDate()
    */
    const birthday = res.data.userData.birthday.toDate();
    // ERROR: .toDate is undefined
})...

-> Code which works (no server side):

 // Client side 
 const userData = await userRef.get().then((doc) => ... return doc.data());
 console.log(userData.birthday);
 /*
    t {
        "nanoseconds": 1607618708,
        "seconds": 615000000,
     } 
 */
 const birthday = userData.birthday.toDate(); // WORKS GOOD

Thank you.

2 Answers

Callable functions only serialize objects to JSON. When the SDK serializes a Timestamp, it merely takes its fields and constructs a new JSON object out of it. That object has no formal type. It is just a plain object with the two fields of data - seconds and nanoseconds - that it found inside the object.

The client is going to receive that JSON with the two fields, but not necessarily know that it came from a Timestamp. You will have to write code on the client app to convert that JSON object with seconds and nanos back into a Timestamp, if that's what it want to use. Once you have seconds and nanos, you can simply create a new Timestamp with its constructor (new Timestamp(seconds, nanos)). Then you can call toDate() on that Timestamp. There is really no shortcut for this, except for you provide for yourself.

you could try:

if(userData.birthday.toString.contains('_seconds'){
return Timestamp(userData.birthday['_seconds'], userData.birthday['_nanoseconds']);
}else{
return Timestamp(userData.birthday);
}
Related