React - 显示 firestore 时间戳 [英] React - display a firestore timestamp

查看:23
本文介绍了React - 显示 firestore 时间戳的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚如何在 React 应用中显示 firestore 时间戳.

我有一个 Firestore 文档,其中包含一个名为 createdAt 的字段.

我正在尝试将其包含在输出列表中(在此处提取相关位,以便您不必通读整个字段列表).

componentDidMount() {this.setState({loading: true });this.unsubscribe = this.props.firebase.用户().onSnapshot(快照=> {让用户 = [];快照.forEach(doc =>users.push({ ...doc.data(), uid: doc.id }),);this.setState({用户,加载:假,});});}componentWillUnmount() {this.unsubscribe();}使成为() {const { 用户,正在加载 } = this.state;返回 (<div>{加载&&<div>加载中...</div>}{users.map(user => (<段落键={user.uid}>{用户.email}{用户名}{user.createdAt.toDate()}{user.createdAt.toDate}{user.createdAt.toDate()).toDateString()}

唯一不会呈现的属性是日期.

上述每一次尝试都会产生一个错误:

<块引用>

TypeError: 无法读取未定义的属性toDate"

我看过

下一次尝试

在尝试找到一种方法在 Firestore 中记录日期以允许我读回它时出现的一件奇怪的事情是,当我以一种形式更改我的提交处理程序以使用此公式时:

handleCreate = (event) =>{const { form } = this.formRef.props;form.validateFields((err, values) => {如果(错误){返回;};常量有效载荷 = {名称:values.name,//createdAt: this.fieldValue.Timestamp()//createdAt: this.props.firebase.fieldValue.serverTimestamp()}console.log("formvalues", 有效载荷);//console.log(_firebase.fieldValue.serverTimestamp());this.props.firebase.doCreateUserWithEmailAndPassword(values.email, values.password).then(authUser => {返回 this.props.firebase.user(authUser.user.uid).set({名称:values.name,电子邮件:values.email,createdAt: 新日期()//.toISOString()//createdAt: this.props.firebase.fieldValue.serverTimestamp()},{合并:真},);//console.log(this.props.firebase.fieldValue.serverTimestamp())}).then(() => {返回 this.props.firebase.doSendEmailVerification();})//.then(() => {message.success("Success") }).then(() => {this.setState({ ...initialValues });this.props.history.push(ROUTES.DASHBOARD);})});event.preventDefault();};

这可以在数据库中记录日期.

firestore 条目的形式如下所示:

我正在尝试在此组件中显示日期:

class UserList 扩展组件 {构造函数(道具){超级(道具);this.state = {加载:假,用户:[],};}componentDidMount() {this.setState({loading: true });this.unsubscribe = this.props.firebase.用户().onSnapshot(快照=> {让用户 = [];快照.forEach(doc =>users.push({ ...doc.data(), uid: doc.id }),);this.setState({用户,加载:假,});});}componentWillUnmount() {this.unsubscribe();}使成为() {const { 用户,正在加载 } = this.state;返回 (<div>{加载&&<div>加载中...</div>}<列表itemLayout="水平"数据源={用户}renderItem={item =>(<List.Item key={item.uid}><List.Item.Meta标题={item.name}描述={项目.组织}/>{item.email}{item.createdAt}{item.createdAt.toDate()}{item.createdAt.toDate().toISOString()}</List.Item>//))}/>

);}}导出默认 withFirebase(UserList);

当我尝试回读时 - 使用:

{item.email}

错误信息如下:

<块引用>

错误:对象作为 React 子对象无效(发现:时间戳(秒=1576363035,纳秒=52000000)).如果你想渲染一组孩子,请改用数组.在项目中(在 UserIndex.jsx:74)

当我尝试使用每一种尝试时:

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

我收到一条错误消息:

<块引用>

TypeError: 无法读取未定义的属性toDate"

基于回读记录在其他字段中的同一文档中的条目的能力,我希望这些条目中的任何一个都能产生输出——即使它没有按照我想要的方式进行格式化.这不会发生.

下一次尝试

以 Waelmas 为例,我尝试按照说明进行操作,但在第一步中我们没有得到相同的响应.在 Walemas 基于 .toDate() 扩展名获取输出的地方,我收到一条错误消息,说 toDate() 不是函数.

与 Firebase 文档一致,我尝试过:

 const docRef = this.props.firebase.db.collection("users").doc("HnH5TeCU1lUjeTqAYJ34ycjt78w22");docRef.get().then(function(docRef) {如果(文档存在){console.log("文档 createdAt:", docRef.createdAt.toDate());

}})

这会产生一串语法错误,我找不到解决方法.

下一次尝试

然后我尝试制作一个新表单,看看我是否可以在没有用户表单的身份验证方面进行探索.

我有一个接受输入的表单:

this.props.firebase.db.collection("insights").add({标题:标题,文字:文字,//createdAt1: new Date(),createdAt: this.props.firebase.fieldValue.serverTimestamp()})

在之前的表单中,new Date() 尝试在数据库中记录日期,在本例中, createdAt 和 createdAt1 的两个字段都生成相同的数据库条目:

{item.createdAt.toDate()}

{item.createdAt.toDate()}

当我尝试输出日期的值时,第一个会产生一个错误:

<块引用>

对象作为 React 子对象无效(找到:Sun Dec 15 201921:33:32 GMT+1100(澳大利亚东部夏令时间)).如果你想渲染一组孩子,使用数组代替

第二个产生错误说:

<块引用>

TypeError: 无法读取未定义的属性toDate"

我不知道下一步该尝试什么.

我看到这篇文章表明以下可能会做一些有用的事情:

 {item.createdAt1.Date.valueOf()}

它没有.它呈现一个错误,说:

<块引用>

类型错误:无法读取未定义的属性日期"

这个帖子似乎有同样的问题和我一样,但没有讨论他们如何设法显示他们存储的日期值.

这个帖子似乎陷入了数组错误消息,但似乎已经找到了如何使用 createdAt.toDate() 显示日期

解决方案

经过一番讨论,我们发现 OPs 用户对象中的时间戳可以这样渲染:

render() {const { 用户,正在加载 } = this.state;返回 (<div>{加载&&<div>加载中...</div>}{users.map(user => (<段落键={user.uid}>{用户.email}{用户名}{new Date(user.createdAt.seconds * 1000).toLocaleDateString("en-US")}

<小时>

我在一个虚拟的 React 项目中重新创建了您的示例,并收到了与预期相同的错误.

<块引用>

错误:对象作为 React 子对象无效

我能够使用以下方法正确呈现它,这也适用于您:

{new Date(user.createdAt._seconds * 1000).toLocaleDateString("en-US")}

对于我的示例时间戳,呈现为:

<块引用>

12/30/2019

<小时>

确保您使用的是保存到 Firestore 的时间戳:

createdAt: this.props.firebase.Timestamp.fromDate(new Date())

注意:这里假设您的 firebase.firestore() 实例位于 this.props.firebase.在其他示例中,您使用 this.props.firebase,但这些方法看起来像是您自己创建的辅助方法.

当这个值被获取时,它将是一个具有两个属性的对象——_seconds_nanoseconds.

请务必包含下划线.如果您使用 createdAt.seconds 它将不起作用,它必须是 createdAt._seconds.

<小时>

我尝试过的其他事情:

user.createdAt.toDate() 抛出 toDate() 不是函数.

user.createdAt 抛出 Error: Objects are not valid as a React child

new Date(user.createdAt._nanoseconds) 呈现错误的日期

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).

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:

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.

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

It generates the same error message as above.

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:

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:

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

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:

{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:

    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:

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:

<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:

                {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()

解决方案

After some discussion, we found that the time stamps in OPs user object could be renders as such:

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} 
                    {new Date(user.createdAt.seconds * 1000).toLocaleDateString("en-US")}


I recreated your example in a dummy React project, and received the same error as expected.

Error: Objects are not valid as a React child

I was able to get this to render correctly with the following method, which should also work for you:

{new Date(user.createdAt._seconds * 1000).toLocaleDateString("en-US")}

Which, for my sample timestamp, rendered as:

12/30/2019


Be sure you are using a timestamp that was saved to Firestore as:

createdAt: this.props.firebase.Timestamp.fromDate(new Date())

Note: This is assuming that your instance of firebase.firestore() is at this.props.firebase. In other examples you use this.props.firebase, but those methods look like helper methods that you have created yourself.

When this value is fetched, it will be an object with two properties -- _seconds and _nanoseconds.

Be sure to include the underscore. If you use createdAt.seconds it won't work, it must be createdAt._seconds.


Other things I tried:

user.createdAt.toDate() throws toDate() is not a function.

user.createdAt throws Error: Objects are not valid as a React child

new Date(user.createdAt._nanoseconds) renders the wrong date

这篇关于React - 显示 firestore 时间戳的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆