반응-Firestore 타임 스탬프 표시


10

반응 앱에 Firestore 타임 스탬프를 표시하는 방법을 알아 내려고합니다.

createdAt라는 필드가있는 firestore 문서가 있습니다.

출력 목록에 포함하려고합니다 (전체 필드 목록을 읽을 필요가 없도록 여기에서 관련 비트를 추출).

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

렌더링하지 않는 유일한 속성은 날짜입니다.

위의 각 시도는 다음과 같은 오류를 생성합니다.

TypeError : 정의되지 않은 'toDate'속성을 읽을 수 없습니다

내가 본 이 게시물이 게시물이 게시물에 , 그리고 이 게시물에 그 TODATE을 제안 그들처럼 다른 사람을, () 작동합니다. 그러나이 확장은 나에게 toString 확장을 시도 할 때를 포함하여 오류를 발생시킵니다.

user.createdAt를 시도 할 때 초 안에 객체를 발견했다는 오류가 발생하기 때문에 firestore에 무언가가 있다는 것을 알고 있습니다.

아래의 Waelmas에서 예를 들어, 필드의 출력을 다음과 같이 기록하려고했습니다.

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

}

또한 이것을 내 맵 문에 추가하려고 시도했지만 user.get이 함수가 아니라는 오류가 발생했습니다.

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

위와 동일한 오류 메시지를 생성합니다.

여기에 이미지 설명을 입력하십시오

다음 공격

Firestore에서 날짜를 기록하여 다시 읽을 수있는 방법을 찾으려고 시도한 이상한 점은 제출 핸들러를 한 형식으로 변경 하여이 공식을 사용한다는 것입니다.

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

데이터베이스에 날짜를 기록하는 데 효과적입니다.

firestore 항목의 형식은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

이 구성 요소에 날짜를 표시하려고합니다.

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

다시 읽으려고하면 다음을 사용하십시오.

{item.email}

오류 메시지는 다음과 같습니다.

오류 : 개체가 React 자식으로 유효하지 않습니다 (발견 : Timestamp (seconds = 1576363035, nanoseconds = 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) {
    if (doc.exists) {
        console.log("Document createdAt:", docRef.createdAt.toDate());

}})

이것은 구문에 오류가 발생하여 그 주위에 방법을 찾을 수 없습니다.

다음 공격

그런 다음 사용자 양식의 인증 측면없이이를 탐색 할 수 있는지 확인하기 위해 새 양식을 만들려고했습니다.

다음과 같이 입력하는 양식이 있습니다.

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

이전 양식에서 new Date () 시도는 데이터베이스에 날짜를 기록하려고 시도한 경우 (이 예에서는 createdAt 및 createdAt1에 대한 두 필드 모두 동일한 데이터베이스 항목을 생성 함)

여기에 이미지 설명을 입력하십시오

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

날짜 값을 출력하려고하면 첫 번째 값이 다음과 같은 오류를 생성합니다.

개체는 React 자식으로 유효하지 않습니다 (발견 : Sun Dec 15 2019 21:33:32 GMT + 1100 (호주 동부 일광 절약 시간)). 자식 컬렉션을 렌더링하려면 대신 배열을 사용하십시오.

두 번째는 다음과 같은 오류를 생성합니다.

TypeError : 정의되지 않은 'toDate'속성을 읽을 수 없습니다

나는 다음에 무엇을 시도해야하는지에 대한 아이디어를 고집하고있다

다음 게시물 이 유용한 것을 제안하는 이 게시물 을 보았습니다 .

                {item.createdAt1.Date.valueOf()}

그렇지 않습니다. 다음과 같은 오류가 발생합니다.

TypeError : 정의되지 않은 '날짜'속성을 읽을 수 없습니다

게시물 은 나와 같은 문제가있는 것 같지만 저장된 날짜 값을 표시하는 방법에 대해서는 다루지 않습니다.

게시물 은 배열 오류 메시지에 붙어있는 것처럼 보이지만 createdAt.toDate ()를 사용하여 날짜를 표시하는 방법을 알아 낸 것 같습니다.

답변:


1

토론을 마친 후 OPs 사용자 개체의 타임 스탬프가 다음과 같이 렌더링 될 수 있음을 발견했습니다.

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 프로젝트에서 예제를 다시 작성했으며 예상대로 동일한 오류가 발생했습니다.

오류 : 개체가 반응 자식으로 유효하지 않습니다

다음 방법으로 올바르게 렌더링 할 수 있었으며, 이는 또한 당신에게도 효과적입니다.

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

샘플 타임 스탬프의 경우 다음과 같이 렌더링됩니다.

2019 년 12 월 30 일


다음과 같이 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() is not a function.

user.createdAt 던지다 Error: Objects are not valid as a React child

new Date(user.createdAt._nanoseconds) 잘못된 날짜를 렌더링


안녕-제안 주셔서 감사합니다. 나는이 시도하고 말한다 오류 얻을 : 형식 오류를 : 읽을 수 없습니다 재산 '타임 스탬프'정의의

나는 또한 시도 : createdAt : 형식 오류 :라는 오류를 반환 firebase.firestore.fieldValue.serverTimestamp () FROMDATE (새 Date ())가, 정의의 읽을 수 없습니다 재산 'fieldValue의'.

이 방법은 효과가 없었지만 사용했던 형식을 사용하려고 생각하는 방법을 이해하고 싶습니다. 설명서에 나와 있지 않습니다. 내가 당신에게 맞는 것을 발견 한 방법을 배울 수 있다면, 그것은 나를 위해 맞는 방법을 찾을 수있게 해줄 것입니다. (나는 왜 그것이 모두에게 같은 것이 아닌지 이해하지 못합니다.하지만 시도 할 새로운 아이디어가 필요합니다. ). 도와 주셔서 감사합니다.
Mel

내가 할 수있는 일은 createdAt : this.props.firebase.fieldValue.serverTimestamp (),
Mel


5

Firestore에서 타임 스탬프를 받으면 다음과 같은 유형입니다.

여기에 이미지 설명을 입력하십시오

이것을 일반 타임 스탬프로 변환하려면 .toDate () 함수를 사용할 수 있습니다.

예를 들어 다음과 같은 문서의 경우 :

여기에 이미지 설명을 입력하십시오

우리는 다음과 같은 것을 사용할 수 있습니다 :

db.collection('[COLLECTION]').doc('[DOCUMENT]').get().then(function(doc) {
  console.log(doc.data().[FIELD].toDate());
});

출력은 다음과 같습니다.

2019-12-16T16:27:33.031Z

이제 해당 타임 스탬프를 추가로 처리하기 위해 문자열로 변환하고 정규식을 사용하여 필요에 따라 수정할 수 있습니다.

예를 들면 다음과 같습니다 (여기서는 Node.js를 사용하고 있습니다).

db.collection('[COLLECTION]').doc('[DOCUMENT]').get().then(function(doc) {
  var stringified = doc.data().[FIELD].toDate().toISOString();
  //console.log(stringified);
  var split1 = stringified.split('T');
  var date = split1[0].replace(/\-/g, ' ');
  console.log(date);
  var time = split1[1].split('.');
  console.log(time[0]);
});

다음과 같은 출력을 제공합니다.

여기에 이미지 설명을 입력하십시오


예를 들어 주셔서 감사합니다. 내 시도에서 같은 구조를 가지고 있습니다. 문서의 모든 문자열 값을 반환하지만 날짜는 반환하지 않습니다. 대신 위에 게시 한 메시지와 함께 오류가 발생합니다. 말이되지 않습니다. toISOString () 확장을 추가하려고했지만 오류 메시지를 변경하지 않습니다 (단지 형식화해야 함)
Mel

콘솔에 타임 스탬프 값을 기록 할 수 있습니까? 올바른 유형의 Firestore 타임 스탬프인지 확인하기 만하면됩니다. @ 멜
Waelmas

아니요-콘솔 로그가 작동하지 않습니다-오류가 발생하지만 날짜가 테이블의 createdAt 필드에 기록됩니다. 이제 다시 읽으려고합니다. 나는 여기에 내가 (안 중포 기지 문서 당) 기록에 날짜를 얻었는지 설명하는 게시물을 작성 : stackoverflow.com/questions/59257755/...
멜에게

공식 문서에서 권장하는 것과 다른 접근 방식을 따르고 있기 때문에 실제로 무엇이 잘못되었는지 잘 모르겠습니다. 처음에 타임 스탬프를 생성하고 푸시하는 방식이 다소 잘못되었습니다. 타임 스탬프를 Firestore에 저장하려면 대답의 시작 부분에서 언급 한 형식의 객체 여야합니다. 이렇게하면 유효한 타임 스탬프로 인식되어 .toDate ()와 함께 사용할 수 있습니다. Firestore.Timestamp.now ()는 올바른 형식의 타임 스탬프를 제공합니다. @ 멜
Waelmas

공식 문서를 따라 타임 스탬프를 만들려고했습니다. 나는 그것을 작동시킬 수 없었다. 나는 날짜를 기록하는 다른 방법으로 우연히 발견했으며 이제 출력을 다시 읽을 수 없습니다! 너무 실망. 어쨌든 도와 주셔서 감사합니다.
Mel

2

따라서 firestore는 날짜를 초와 나노초로 객체로 저장합니다. 사용자가 생성 된 시간을 원하면 참조하십시오.user.createdAt.nanoseconds . 유닉스 타임 스탬프를 반환합니다.

앱에 날짜를 어떻게 표시 하시겠습니까? 날짜 객체를 얻으려면 타임 스탬프를 날짜 생성자에 전달할 수 있습니다 new Date(user.createdAt.nanoseconds). 개인적으로 나는 시간 처리 를 위해 date-fns 라이브러리를 사용하는 것을 좋아합니다 .


감사합니다-이 제안을 시도했습니다. TypeError : 정의되지 않은 'nanoseconds'속성을 읽을 수 없습니다. 나는 당신이 지금 제안한 라이브러리를 살펴볼 것입니다
Mel

생성 한 로그를 작성하여 공유하십시오. 데이터의 비동기 특성을 고려할 때 아마도 그렇게 반환해야 할 것입니다 user.createdAt && new Date(user.createdAt.nanoseconds). Date-fns는이 문제에 도움이되지 않습니다. 날짜가 있으면 날짜를 표시하는 편리한 라이브러리입니다.
조쉬 피트 맨

createdAt는 긴 드롭 다운 메뉴 목록을 기록합니다. firestore의 필드에 표시된 날짜가 포함 된 날짜를 찾을 수 없습니다. 첫 부분은 다음과 같습니다. createdAt : ServerTimestampFieldValueImpl _methodName : "FieldValue.serverTimestamp" proto : FieldValueImpl 생성자 : ƒ ServerTimestampFieldValueImpl () 인스턴스 : ServerTimestampFieldValueImpl _methodName : "FieldValue.serverTimestamp" proto : FieldValueImpl 생성자 : ƒ ServerTimestampFieldValueImpl FieldValue.serverTimestamp "} 인수 : (...) 호출자 : (...)
Mel

타임 스탬프 기능을 실제 타임 스탬프가 아닌 데이터베이스로 푸시 한 것 같습니다. 타임 스탬프는 어떻게 설정합니까? firestore.FieldValue.serverTimestamp()
Josh Pittman '12

firestore에 표시된 항목은 내가 첨부 한 사진입니다. 이것은 항목입니다 : this.props.firebase.fieldValue.serverTimestamp ()
Mel

2

Firestore에 날짜를 보내는 방법 :

import firebase from 'firebase/app';

// ..........
// someObject is the object you're saving to your Firestore.

someObject.createdAt: firebase.firestore.Timestamp.fromDate(new Date())

다시 읽는 방법 :

function mapMonth(monthIndex) {
  const months = {
    0: 'jan',
    1: 'feb',
    2: 'mar',
    3: 'apr',
    4: 'may',
    5: 'jun',
    6: 'jul',
    7: 'aug',
    8: 'sep',
    9: 'oct',
    10: 'nov',
    11: 'dec'
  };
  return months[monthIndex];
}

// ..........
// Here you already read the object from Firestore and send its properties as props to this component.

return(
    <LS.PostDate_DIV>
      Published on {mapMonth(props.createdAt.toDate().getMonth()) + ' '}
      of {props.createdAt.toDate().getFullYear()}
    </LS.PostDate_DIV>
  );
}

기본적으로 createdAt.toDate()JS Date 객체를 얻습니다.

나는 항상 이렇게 사용합니다!

보낸 사람 : https://cloud.google.com/firestore/docs/manage-data/add-data

여기에 이미지 설명을 입력하십시오

사용자의 시스템 날짜를 기준으로 데이터가 생성됩니다. DB에 모든 것이 시간 순서대로 (사용자 시스템에 의해 설정된 잘못된 시스템 날짜의 오류없이) 저장되도록하려면 서버 타임 스탬프를 사용해야합니다. 날짜는 Firestore DB 내부 날짜 시스템을 사용하여 설정됩니다.

여기에 이미지 설명을 입력하십시오


이것에 감사하지만 극복하려는 문제는 데이터베이스에 기록 된 날짜를 표시하는 방법을 찾을 수 없다는 것입니다. 내가 공유 한 종류의 오류가 계속 발생합니다.
Mel

2

createdAt특성이 설정되어 있는 사용자의 문서 ID로 다음을 시도하십시오.

const docRef = db.collection("users").doc("[docID]");

docRef.get().then(function(docRef) {
  if (docRef.exists) {
     console.log("user created at:", docRef.data().createdAt.toDate());
  }
})

.data()문서의 속성에 액세스하기 전에 메서드 를 호출하는 것이 중요 하지 않습니다.

속성이 설정되지 않은 docRef.data().createdAt.toDate()사용자 에게 액세스 createdAt하면TypeError: Cannot read property 'toDate' of undefined

따라서 컬렉션에 createdAt속성이 정의 되지 않은 사용자가있는 경우 . 사용자에게 createdAt속성 이 있는지 확인 하기 전에 로직을 구현해야 합니다. 다음과 같이 할 수 있습니다 :

//This code gets all the users and logs it's creation date in the console
docRef.get().then(function(docRef) {
  if (docRef.exists && docRef.data().createdAt) {
      console.log("User created at:", docRef.data().createdAt.toDate());
  }
})

위에서 볼 수 있듯이 문서 필드 요청에 data ()를 사용합니다. 내가 그렇지 않으면 다른 필드는 렌더링되지 않습니다. 구체적인 문제는 타임 스탬프와 관련이 있으며 렌더링되지 않습니다. 위에서 시도한 시도 중 하나에는 toDate () 확장을 사용한 시도가 포함됩니다. 위에서 설명한 이유로 작동하지 않습니다. 어쨌든 시간 내 주셔서 감사합니다.
Mel

0

과거에 중첩 객체 속성 item.someProp이 객체로 간주되는 목록에서 올바르게 렌더링되지 않는 문제가 발생 했지만 in item.someProp.someSubProp값으로 해결되지는 않습니다 .someSubPropitem.someProp

따라서 문제를 해결하기 위해 사용자 개체를 만들 때 타임 스탬프를 일반 날짜 개체 (또는 원하는 표시 형식)로 평가하지 않는 이유는 무엇입니까?

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

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

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

또한 가치가 모두 것을주의 DocumentSnapshot#data()DocumentSnapshot#get()지정 방법하지 아직 확정 처리하는 것을 목적 받아 FieldValue.serverTimestamp()값을. 기본적으로 아직 완료되지 않은 상태는 단순히 null입니다. 를 사용 { serverTimestamps: "estimate"}하면 이러한 null 값이 예상치로 변경됩니다.
samthecodingman

안녕-제안 주셔서 감사합니다. 시도하고 싶지만 이해하지 못합니다-또는 구현 방법. 이 제안을 적용 할 때 적용 할 원칙에 대한 규칙이 있습니까? 접근 방식에 대한 문헌을 찾을 수 있으면 코드에서 시도 할 수 있도록 아이디어가 어떻게 작동하는지 알아 보겠습니다.
Mel

몇 년 동안 다른 StackOverflow 질문 을 검토 한 후 선택했을 때 특별한 리소스가 없습니다 .
samthecodingman

공유해 주셔서 감사합니다. 오늘 밤에 읽을 게요
Mel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.