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

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

问题描述

我试图弄清楚如何在React应用中显示Firestore时间戳.

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

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

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:无法读取未定义的属性"toDate"

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.

我知道它知道Firestore中有什么东西,因为当我尝试user.createdAt时,我收到一条错误消息,说它找到了其中包含秒数的对象.

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.

以下面的Waelmas为例,我尝试将字段的输出记录为:

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

}

我还尝试将其添加到map语句中,但收到一条错误消息,指出user.get不是函数.

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.

下次尝试

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

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.

firestore条目的形式如下:

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}

{item.email}

错误消息显示为:

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

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

我看到一条错误消息:

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

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.

下次尝试

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

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.

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

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.

下次尝试

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

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

在以前的形式中,新的Date()尝试在数据库中记录了一个日期,在此示例中,createdAt和createdAt1的两个字段都生成相同的数据库条目:

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:

对象作为React子对象无效(发现:2019年12月15日,星期日) 21:33:32 GMT + 1100(澳大利亚东部夏令时间).如果你想 渲染孩子的集合,请改用数组

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

第二个错误产生:

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

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:无法读取未定义的属性日期"

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.

帖子似乎卡在了数组错误上消息,但似乎已经知道如何使用createdAt.toDate()显示日期了

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

推荐答案

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

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")}


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


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

错误:对象无效,不能作为React子代

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

12/30/2019


确保您使用的时间戳记已另存为Firestore:


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

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

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

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.

获取此值时,它将是具有两个属性的对象-_seconds_nanoseconds.

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

确保包含下划线.如果您使用createdAt.seconds,则无法使用,必须为createdAt._seconds.

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

我尝试过的其他事情:

user.createdAt.toDate()抛出toDate() is not a function.

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

new Date(user.createdAt._nanoseconds)显示错误的日期

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

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