MauriceNino
MauriceNino

Reputation: 6757

Extract TImestamp from the result of a Function

So I have an interface like this:

interface Test {
    // ...
    created_at: Timestamp;
    // ...
}

and I return an object from a function like this:

export const getTest = functions.https.onCall(async (data, context) => {
    if (!context.auth) {
        return null;
    }

    let snap = await admin
                 .firestore()
                 .collection('test')
                 .get();

    return snap.docs.map(r => ({ // Add id to the output
        id: r.id,
        ...r.data()
    })[0];
});

So I should be getting the timestamp object in my application, but this is what I get in the chrome console, when I try to get the object from the function like so:

// Using AngularFireFunctions
let result: Test = await this.fns.httpsCallable<void, Test>('getTest')().toPromise();

This is the whole content of result.created_at:

enter image description here

When I call result.created_at.toDate() I get an ....created_at.toDate is not a function error.

What can I do to change this?

This is what I am stuck with right now:

result.created_at = new Date(result.created_at._seconds * 1000);

Upvotes: 0

Views: 103

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317758

It looks like you’re expecting the callable function to retain the data type of the objects returned from it. That’s not quite how it works. The function will serialize the passed objects as JSON, losing all object type information, including the Timestamp type. The Timestamp is being serialized using its internal representation, which is what you’re seeing in the log output. I wouldn’t write code that depends on this, as it's obviously using hidden implementation details.

What you should probably do instead is convert that Timestamp into a normal JavaScript object, and use that in the returned result. Then, on the client side, you will need to write code that understands how you’ve chosen to represent that timestamp. It is extra work, but it insulates the client from knowing those private implementation details.

I suggest putting the seconds and nanoseconds part of the Timestamp into a plain old object, replacing the existing Timestamp field, then converting that object back into a Timestamp on the client using the Timestamp constructor that takes the seconds and nanos components as arguments.

Upvotes: 2

Related Questions