OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How can I display a Firestore timestamp in React?

  • Thread starter Thread starter Mel
  • Start date Start date
M

Mel

Guest
I am trying to figure out how to display a firestore timestamp in a react app.

I have a firestore document with a field named createdAt.

I am trying to include it in a list of output (extracting the relevant bits here so that you don't have to read through the entire list of fields).

Code:
componentDidMount() {
    this.setState({ loading: true });

    this.unsubscribe = this.props.firebase
      .users()
      .onSnapshot(snapshot => {
        let users = [];

        snapshot.forEach(doc =>
          users.push({ ...doc.data(), uid: doc.id }),
        );

        this.setState({
          users,
          loading: false,
        });
      });
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const { users, loading } = this.state;

    return (
        <div>
    {loading && <div>Loading ...</div>}

            {users.map(user => (

                <Paragraph key={user.uid}>  

       <key={user.uid}>  
       {user.email}
       {user.name}
       {user.createdAt.toDate()}
       {user.createdAt.toDate}
       {user.createdAt.toDate()).toDateString()}

The only attribute that won't render is the date.

Each of the above attempts generates an error that says:

TypeError: Cannot read property 'toDate' of undefined

I have seen this post, and this post and this post, and this post and others like them, which suggest that toDate() should work. But - this extension throws an error for me - including when I try the toString extension.

I know it knows there is something in firestore because when I try user.createdAt, I get an error saying it found an object with seconds in it.

Taking the example from Waelmas below, I tried to log the output of the field as:

Code:
this.db.collection('users').doc('HnH5TeCU1lUjeTqAYJ34ycjt78w22').get().then(function(doc) {
  console.log(doc.data().createdAt.toDate());

}

I also tried adding this to my map statement but get an error that says user.get is not a function.

Code:
{user.get().then(function(doc) {
                    console.log(doc.data().createdAt.toDate());}
                  )}

It generates the same error message as above.

enter image description here

NEXT ATTEMPT

One strange thing that has come up in trying to find a way to record a date in Firestore that allows me to then read it back, is that when I change my submit handler in one form to use this formulation:

Code:
handleCreate = (event) => {
    const { form } = this.formRef.props;
    form.validateFields((err, values) => {
      if (err) {
        return;
      };
    const payload = {
    name: values.name,
    // createdAt: this.fieldValue.Timestamp()
    // createdAt: this.props.firebase.fieldValue.serverTimestamp()

    }
    console.log("formvalues", payload);
    // console.log(_firebase.fieldValue.serverTimestamp());


    this.props.firebase
    .doCreateUserWithEmailAndPassword(values.email, values.password)
    .then(authUser => {
    return this.props.firebase.user(authUser.user.uid).set(
        {
          name: values.name,
          email: values.email,
          createdAt: new Date()
          // .toISOString()
          // createdAt: this.props.firebase.fieldValue.serverTimestamp()

        },
        { merge: true },
    );
    // console.log(this.props.firebase.fieldValue.serverTimestamp())
    })
    .then(() => {
      return this.props.firebase.doSendEmailVerification();
      })
    // .then(() => {message.success("Success") })
    .then(() => {
      this.setState({ ...initialValues });
      this.props.history.push(ROUTES.DASHBOARD);

    })


  });
  event.preventDefault();
    };

That works to record a date in the database.

The form of the firestore entry looks like this:

enter image description here

I'm trying to display a date in this component:

Code:
class UserList extends Component {
  constructor(props) {
    super(props);

    this.state = {
      loading: false,
      users: [],
    };
  }

  componentDidMount() {
    this.setState({ loading: true });

    this.unsubscribe = this.props.firebase
      .users()
      .onSnapshot(snapshot => {
        let users = [];

        snapshot.forEach(doc =>
          users.push({ ...doc.data(), uid: doc.id }),
        );

        this.setState({
          users,
          loading: false,
        });
      });
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const { users, loading } = this.state;

    return (
      <div>
          {loading && <div>Loading ...</div>}

          <List
            itemLayout="horizontal"
            dataSource={users}

            renderItem={item => (
              <List.Item key={item.uid}>
                <List.Item.Meta
                  title={item.name}
                  description={item.organisation}
                />
                  {item.email}
                  {item.createdAt}
                  {item.createdAt.toDate()}
                  {item.createdAt.toDate().toISOString()}

              </List.Item>
            // )
          )}
          />

      </div>
    );
  }
}

export default withFirebase(UserList);

When I try to read it back - using:

{item.email}

The error message reads:

Error: Objects are not valid as a React child (found: Timestamp(seconds=1576363035, nanoseconds=52000000)). If you meant to render a collection of children, use an array instead. in Item (at UserIndex.jsx:74)

When I try using each of these attempts:

Code:
{item.createdAt}
{item.createdAt.toDate()}
{item.createdAt.toDate().toISOString()}

I get an error that says:

TypeError: Cannot read property 'toDate' of undefined

Based on the ability to read back entries logged in the same document in other fields, I'm expecting any of these to work to produce output -even if it's not formatted in the way I want. That doesn't happen.

NEXT ATTEMPT

Taking Waelmas' example, I tried to follow the instructions, but where we aren't getting the same response is in the first step. Where Walemas gets an output based on the .toDate() extension, I get an error saying toDate() is not a function.

Consistent with the Firebase documentation, I tried:

Code:
    const docRef = this.props.firebase.db.collection("users").doc("HnH5TeCU1lUjeTqAYJ34ycjt78w22");

docRef.get().then(function(docRef) {
    if (doc.exists) {
        console.log("Document createdAt:", docRef.createdAt.toDate());

} })

This produces a string of errors with the syntax and I can't find a way around them.

NEXT ATTEMPT

I then tried making a new form to see if I could explore this without the authentication aspect of the users form.

I have a form that takes input as:

Code:
this.props.firebase.db.collection("insights").add({
            title: title,
            text: text,
            // createdAt1: new Date(),
            createdAt: this.props.firebase.fieldValue.serverTimestamp()
        })

Where in the previous form, the new Date() attempt worked to record a date in the database, in this example both fields for createdAt and createdAt1 generate the same database entry:

enter image description here

Code:
<div>{item.createdAt.toDate()}</div>
                    <div>{item.createdAt.toDate()}</div>

When I try to output the value of the dates, the first one generates an error that says:

Objects are not valid as a React child (found: Sun Dec 15 2019 21:33:32 GMT+1100 (Australian Eastern Daylight Time)). If you meant to render a collection of children, use an array instead

The second generates the error saying:

TypeError: Cannot read property 'toDate' of undefined

I'm stuck for ideas on what to try next.

I saw this post that suggests that the following might do something useful:

Code:
                {item.createdAt1.Date.valueOf()}

It doesn't. It renders an error that says:

TypeError: Cannot read property 'Date' of undefined

This post seems to be having the same trouble as me, but doesn't go into how they managed to display the date value they stored.

This post seems to be getting stuck at the array error message, but seems to have figured out how to display a date using createdAt.toDate()

<p>I am trying to figure out how to display a firestore timestamp in a react app.</p>

<p>I have a firestore document with a field named createdAt. </p>

<p>I am trying to include it in a list of output (extracting the relevant bits here so that you don't have to read through the entire list of fields).</p>

<pre><code>componentDidMount() {
this.setState({ loading: true });

this.unsubscribe = this.props.firebase
.users()
.onSnapshot(snapshot => {
let users = [];

snapshot.forEach(doc =>
users.push({ ...doc.data(), uid: doc.id }),
);

this.setState({
users,
loading: false,
});
});
}

componentWillUnmount() {
this.unsubscribe();
}

render() {
const { users, loading } = this.state;

return (
<div>
{loading && <div>Loading ...</div>}

{users.map(user => (

<Paragraph key={user.uid}>

<key={user.uid}>
{user.email}
{user.name}
{user.createdAt.toDate()}
{user.createdAt.toDate}
{user.createdAt.toDate()).toDateString()}
</code></pre>

<p>The only attribute that won't render is the date.</p>

<p>Each of the above attempts generates an error that says: </p>

<blockquote>
<p>TypeError: Cannot read property 'toDate' of undefined</p>
</blockquote>

<p>I have seen <a href="https://stackoverflow.com/questions/56035174/firebase-firestore-createdat-timestamps-react">this post</a>, and <a href="https://stackoverflow.com/questions/56727191/typeerror-cannot-read-property-todate-of-undefined">this post</a> and <a href="https://stackoverflow.com/questions...ot-read-property-todate-of-undefined/56727243">this post</a>, and <a href="https://stackoverflow.com/questions...irestore-date-timestamp-to-a-js-date/52247484">this post</a> and others like them, which suggest that toDate() should work. But - this extension throws an error for me - including when I try the toString extension.</p>

<p>I know it knows there is something in firestore because when I try user.createdAt, I get an error saying it found an object with seconds in it.</p>

<p>Taking the example from Waelmas below, I tried to log the output of the field as:</p>

<pre><code>this.db.collection('users').doc('HnH5TeCU1lUjeTqAYJ34ycjt78w22').get().then(function(doc) {
console.log(doc.data().createdAt.toDate());
</code></pre>

<p>}</p>

<p>I also tried adding this to my map statement but get an error that says user.get is not a function.</p>

<pre><code>{user.get().then(function(doc) {
console.log(doc.data().createdAt.toDate());}
)}
</code></pre>

<p>It generates the same error message as above.</p>

<p><a href="https://i.sstatic.net/69jsQ.png" rel="noreferrer"><img src="https://i.sstatic.net/69jsQ.png" alt="enter image description here"></a></p>

<p><strong>NEXT ATTEMPT</strong></p>

<p>One strange thing that has come up in trying to find a way to record a date in Firestore that allows me to then read it back, is that when I change my submit handler in one form to use this formulation:</p>

<pre><code>handleCreate = (event) => {
const { form } = this.formRef.props;
form.validateFields((err, values) => {
if (err) {
return;
};
const payload = {
name: values.name,
// createdAt: this.fieldValue.Timestamp()
// createdAt: this.props.firebase.fieldValue.serverTimestamp()

}
console.log("formvalues", payload);
// console.log(_firebase.fieldValue.serverTimestamp());


this.props.firebase
.doCreateUserWithEmailAndPassword(values.email, values.password)
.then(authUser => {
return this.props.firebase.user(authUser.user.uid).set(
{
name: values.name,
email: values.email,
createdAt: new Date()
// .toISOString()
// createdAt: this.props.firebase.fieldValue.serverTimestamp()

},
{ merge: true },
);
// console.log(this.props.firebase.fieldValue.serverTimestamp())
})
.then(() => {
return this.props.firebase.doSendEmailVerification();
})
// .then(() => {message.success("Success") })
.then(() => {
this.setState({ ...initialValues });
this.props.history.push(ROUTES.DASHBOARD);

})


});
event.preventDefault();
};
</code></pre>

<p>That works to record a date in the database.</p>

<p>The form of the firestore entry looks like this:</p>

<p><a href="https://i.sstatic.net/7Lc7c.png" rel="noreferrer"><img src="https://i.sstatic.net/7Lc7c.png" alt="enter image description here"></a></p>

<p>I'm trying to display a date in this component:</p>

<pre><code>class UserList extends Component {
constructor(props) {
super(props);

this.state = {
loading: false,
users: [],
};
}

componentDidMount() {
this.setState({ loading: true });

this.unsubscribe = this.props.firebase
.users()
.onSnapshot(snapshot => {
let users = [];

snapshot.forEach(doc =>
users.push({ ...doc.data(), uid: doc.id }),
);

this.setState({
users,
loading: false,
});
});
}

componentWillUnmount() {
this.unsubscribe();
}

render() {
const { users, loading } = this.state;

return (
<div>
{loading && <div>Loading ...</div>}

<List
itemLayout="horizontal"
dataSource={users}

renderItem={item => (
<List.Item key={item.uid}>
<List.Item.Meta
title={item.name}
description={item.organisation}
/>
{item.email}
{item.createdAt}
{item.createdAt.toDate()}
{item.createdAt.toDate().toISOString()}

</List.Item>
// )
)}
/>

</div>
);
}
}

export default withFirebase(UserList);
</code></pre>

<p>When I try to read it back - using:</p>

<p>{item.email}</p>

<p>The error message reads: </p>

<blockquote>
<p>Error: Objects are not valid as a React child (found:
Timestamp(seconds=1576363035, nanoseconds=52000000)). If you meant to
render a collection of children, use an array instead.
in Item (at UserIndex.jsx:74)</p>
</blockquote>

<p>When I try using each of these attempts:</p>

<pre><code>{item.createdAt}
{item.createdAt.toDate()}
{item.createdAt.toDate().toISOString()}
</code></pre>

<p>I get an error that says:</p>

<blockquote>
<p>TypeError: Cannot read property 'toDate' of undefined</p>
</blockquote>

<p>Based on the ability to read back entries logged in the same document in other fields, I'm expecting any of these to work to produce output -even if it's not formatted in the way I want. That doesn't happen.</p>

<p><strong>NEXT ATTEMPT</strong></p>

<p>Taking Waelmas' example, I tried to follow the instructions, but where we aren't getting the same response is in the first step. Where Walemas gets an output based on the .toDate() extension, I get an error saying toDate() is not a function.</p>

<p>Consistent with the Firebase documentation, I tried:</p>

<pre><code> const docRef = this.props.firebase.db.collection("users").doc("HnH5TeCU1lUjeTqAYJ34ycjt78w22");

docRef.get().then(function(docRef) {
if (doc.exists) {
console.log("Document createdAt:", docRef.createdAt.toDate());
</code></pre>

<p>}
})</p>

<p>This produces a string of errors with the syntax and I can't find a way around them.</p>

<p><strong>NEXT ATTEMPT</strong></p>

<p>I then tried making a new form to see if I could explore this without the authentication aspect of the users form.</p>

<p>I have a form that takes input as:</p>

<pre><code>this.props.firebase.db.collection("insights").add({
title: title,
text: text,
// createdAt1: new Date(),
createdAt: this.props.firebase.fieldValue.serverTimestamp()
})
</code></pre>

<p>Where in the previous form, the new Date() attempt worked to record a date in the database, in this example both fields for createdAt and createdAt1 generate the same database entry:</p>

<p><a href="https://i.sstatic.net/Shcfm.png" rel="noreferrer"><img src="https://i.sstatic.net/Shcfm.png" alt="enter image description here"></a></p>

<pre><code><div>{item.createdAt.toDate()}</div>
<div>{item.createdAt.toDate()}</div>
</code></pre>

<p>When I try to output the value of the dates, the first one generates an error that says:</p>

<blockquote>
<p>Objects are not valid as a React child (found: Sun Dec 15 2019
21:33:32 GMT+1100 (Australian Eastern Daylight Time)). If you meant to
render a collection of children, use an array instead</p>
</blockquote>

<p>The second generates the error saying:</p>

<blockquote>
<p>TypeError: Cannot read property 'toDate' of undefined</p>
</blockquote>

<p>I'm stuck for ideas on what to try next.</p>

<p>I saw <a href="https://stackoverflow.com/questions/221294/how-do-you-get-a-timestamp-in-javascript?rq=1">this post</a> that suggests that the following might do something useful:</p>

<pre><code> {item.createdAt1.Date.valueOf()}
</code></pre>

<p>It doesn't. It renders an error that says: </p>

<blockquote>
<p>TypeError: Cannot read property 'Date' of undefined</p>
</blockquote>

<p>This <a href="https://stackoverflow.com/questions/55753570/setting-a-created-timestamp-in-firestore-with-react">post</a> seems to be having the same trouble as me, but doesn't go into how they managed to display the date value they stored.</p>

<p>This <a href="https://stackoverflow.com/questions/58033547/convert-all-array-objectfirestore-timestamp-to-date">post</a> seems to be getting stuck at the array error message, but seems to have figured out how to display a date using createdAt.toDate()</p>
 

Latest posts

Top