Tepki - bir yangın deposu zaman damgası görüntüle


10

Bir tepki app bir firestore zaman damgası görüntülemek nasıl anlamaya çalışıyorum.

Oluşturulan alan adlı bir firestore belgem var.

Çıktı listesine dahil etmeye çalışıyorum (ilgili bitlerin ayıklanması, böylece tüm alanların listesini okumak zorunda değilsiniz).

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

Oluşturulmayacak tek özellik tarihtir.

Yukarıdaki denemelerin her biri şu hata mesajı verir:

TypeError: undefined öğesinin 'toDate' özelliği okunamıyor

Gördüğüm bu yazı ve bu yazı ve bu yazı ve bu yazı ve bu Todate önermek onlar gibi diğerleri, () çalışmalıdır. Ancak - bu uzantı benim için bir hata veriyor - toString uzantısını denediğimde dahil.

Firestore'da bir şey olduğunu biliyorum çünkü user.createdAt'ı denediğimde, içinde saniye olan bir nesne bulduğunu söyleyen bir hata alıyorum.

Aşağıdaki Waelmas'tan örnek alarak, alanın çıktısını şöyle kaydetmeye çalıştım:

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

}

Ben de bu benim harita deyim eklemeyi denedim ama user.get bir işlev değil diyor bir hata alıyorum.

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

Yukarıdaki ile aynı hata mesajını üretir.

resim açıklamasını buraya girin

SONRAKİ GİRİŞ

Firestore'da bir tarihi kaydetmenin bir yolunu bulmaya çalışırken ortaya çıkan garip bir şey, daha sonra tekrar okumama izin veriyor, bu formülü kullanmak için gönderme işleyicimi bir biçimde değiştirdiğimde:

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

Bu veritabanına bir tarih kaydetmek için çalışır.

Firestore girişinin formu şuna benzer:

resim açıklamasını buraya girin

Bu bileşende bir tarih görüntülemeye çalışıyorum:

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

Tekrar okumaya çalıştığımda - kullanarak:

{İtem.email}

Hata mesajında ​​şunlar bulunur:

Hata: Nesneler bir Reaksiyon alt öğesi olarak geçerli değil (bulunan: Zaman damgası (saniye = 1576363035, nanosaniye = 52000000)). Bir çocuk koleksiyonu oluşturmak istiyorsanız, bunun yerine bir dizi kullanın. Öğe'de (UserIndex.jsx'te: 74)

Bu girişimlerin her birini kullanmayı denediğimde:

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

Bir hata mesajı alıyorum:

TypeError: undefined öğesinin 'toDate' özelliği okunamıyor

Aynı belgede diğer alanlara kaydedilmiş girdileri okuma yeteneğine dayanarak, bunların herhangi birinin istediğim şekilde biçimlendirilmemişse çıktı üretmek için çalışmasını bekliyorum. Bu olmaz.

SONRAKİ GİRİŞ

Waelmas'ın örneğini alarak, talimatları takip etmeye çalıştım, ancak aynı cevabı alamadığımız ilk adım. Walemas .toDate () uzantısına dayalı bir çıktı alır, ben toDate () bir işlev olmadığını söyleyerek bir hata alıyorum.

Firebase belgelerine uygun olarak denedim:

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

}})

Bu sözdizimi ile bir dizi hata üretir ve onların etrafında bir yol bulamıyorum.

SONRAKİ GİRİŞ

Daha sonra, kullanıcı formunun kimlik doğrulama özelliği olmadan bunu keşfedip edemeyeceğimi görmek için yeni bir form oluşturmayı denedim.

Ben girdi olarak alır bir formu var:

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

Önceki formda, yeni Date () girişimi veritabanında bir tarih kaydetmeye çalıştığında, bu örnekte createAt ve createdAt1 alanlarının her ikisi de aynı veritabanı girişini oluşturur:

resim açıklamasını buraya girin

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

Tarihlerin değerini çıkarmaya çalıştığımda, ilki şöyle bir hata oluşturur:

Nesneler bir Reaksiyon çocuğu olarak geçerli değil (bulunan: 15 Aralık 2019 Pazar 21:33:32 GMT + 1100 (Avustralya Doğu Yaz Saati)). Bir çocuk koleksiyonu oluşturmak istiyorsanız bunun yerine bir dizi kullanın

İkincisi şu hatayı üretir:

TypeError: undefined öğesinin 'toDate' özelliği okunamıyor

Bir sonraki adımda ne yapacağınıza dair fikirler için takılıp kaldım.

Aşağıdakilerin yararlı bir şeyler yapabileceğini öneren bu yayını gördüm :

                {item.createdAt1.Date.valueOf()}

Öyle değil. Şu hata mesajı verir:

TypeError: undefined öğesinin 'Date' özelliği okunamıyor

Bu gönderi benimle aynı sorunu yaşıyor gibi görünüyor, ancak depoladıkları tarih değerini göstermeyi nasıl başardıklarına bakmıyorlar.

Bu gönderi dizi hata iletisinde takılı kalıyor gibi görünüyor, ancak createAt.toDate () kullanarak bir tarihin nasıl görüntüleneceğini anladıkları anlaşılıyor

Yanıtlar:


1

Bazı tartışmalardan sonra, OP kullanıcı nesnesindeki zaman damgalarının şu şekilde oluşturulabileceğini bulduk:

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

Örneğinizi sahte bir React projesinde yeniden oluşturdum ve beklendiği gibi aynı hatayı aldım.

Hata: Nesneler, Reaksiyon alt öğesi olarak geçerli değil

Bunu, sizin için de çalışması gereken aşağıdaki yöntemle doğru bir şekilde oluşturmayı başardım:

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

Hangi, benim örnek zaman damgası için şu şekilde render:

2019/12/30


Firestore'a şu şekilde kaydedilmiş bir zaman damgası kullandığınızdan emin olun:

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

Not: Bu, örneğinizin firebase.firestore()adresinde olduğunu varsayar this.props.firebase. Diğer örneklerde this.props.firebase öğesini kullanırsınız, ancak bu yöntemler kendi oluşturduğunuz yardımcı yöntemlere benzer.

Bu değer getirildiğinde, iki özelliğe sahip bir nesne olacaktır - _secondsve _nanoseconds.

Alt çizgiyi eklediğinizden emin olun. Eğer kullanırsanız createdAt.seconds, işe yaramaz createdAt._seconds.


Denediğim diğer şeyler:

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

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

new Date(user.createdAt._nanoseconds) yanlış tarih


Merhaba - öneri için teşekkürler. Bunu denedim ve şöyle bir hata alıyorum: TypeError: undefined 'Zaman Damgası' özelliği okunamıyor
Mel

Ayrıca şunu da denedim: createdAt: firebase.firestore.fieldValue.serverTimestamp (). FromDate (new Date ()), şöyle bir hata döndürüyor: TypeError: undefined
Mel

Bu benim için işe yaramasa da, kullandığınız biçimi denemek için nasıl düşündüğünüzü anlamak istiyorum. Belgelerde gösterildiği gibi değil. Sizin için işe yarayan bir şeyi nasıl keşfettiğinizi öğrenebilirsem, benim için işe yarayan bir yol bulmama izin verebilir (bunların neden herkes için aynı şey olmadığını anlamıyorum - ama denemek için yeni fikirlere ihtiyacım var ). Yardım etmeye çalıştığın için tekrar teşekkürler.
Mel

Ne yapabilirim kullanarak (yukarıda gösterildiği gibi) bir tarih kaydetmektir: createdAt: this.props.firebase.fieldValue.serverTimestamp (),
Mel


5

Firestore'dan zaman damgaları aldığınızda bunlar aşağıdaki türdedir:

resim açıklamasını buraya girin

Bunu normal bir zaman damgasına dönüştürmek için .toDate () işlevini kullanabilirsiniz.

Örneğin, aşağıdaki gibi bir belge için:

resim açıklamasını buraya girin

Şöyle bir şey kullanabiliriz:

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

ve çıktı aşağıdaki gibi olacaktır:

2019-12-16T16:27:33.031Z

Şimdi bu zaman damgasını daha fazla işlemek için, bir dizeye dönüştürebilir ve ihtiyaçlarınıza göre değiştirmek için regex'i kullanabilirsiniz.

Örneğin: (Burada Node.js kullanıyorum)

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

Size böyle bir çıktı verecektir:

resim açıklamasını buraya girin


Örnek için teşekkürler. Girişimde aynı yapıya sahibim. Belgedeki tüm dize değerlerini döndürür, ancak tarihi döndürmez. Bunun yerine, yukarıda gönderdiğim iletiyle ilgili bir hata oluşturur. Hiç mantıklı değil. TOISOString () uzantısını eklemeyi denedim ama hata mesajını değiştirmiyor (sadece biçimlendirme olmalı)
Mel

Konsolda zaman damgasının değerini kaydedebilir misiniz? Sadece doğru Firestore zaman damgası türünü doğrulamak için. @Mel
Waelmas

Hayır - konsol günlüğü çalışmaz - bir hata oluşturur - ancak tarih tablodaki createAt alanına kaydedilir - şimdi sadece tekrar okumaya çalışıyorum. Burada kayıt yapmak için tarihi aldım (firebase belgelerine göre değil) açıklayan bir yazı oluşturdum: stackoverflow.com/questions/59257755/…
Mel

Resmi dokümanlar tarafından önerilen yaklaşımdan farklı bir yaklaşım izlediğiniz için, neyin gerçekten yanlış gittiğinden emin değilim. Zaman damgasını yaratma ve itme şekliniz bir şekilde hatalı görünüyor. Firestore'a bir zaman damgası kaydettiğinizde cevabımın başında bahsettiğim formatta bir nesne olması gerekir. Bu şekilde .toDate () ile kullanılabilen geçerli bir zaman damgası olarak tanınır. Firestore.Timestamp.now () size kontrol etmek için doğru formatta bir zaman damgası verecektir. @Mel
Waelmas

Bir zaman damgası oluşturmak için resmi belgeleri takip etmeyi denedim. Çalışamadım. Bir tarih kaydetmek için alternatif bir yol üzerinde tökezledim ve şimdi çıktıyı tekrar okuyamıyorum! Çok sinir bozucu. Yine de yardım etmeye çalıştığın için teşekkürler.
Mel

2

Bu yüzden firestore, tarihleri ​​saniye ve nanosaniye ile bir nesne olarak depolar. Kullanıcının oluşturulduğu saati istiyorsanız, o zaman referans verirsiniz user.createdAt.nanoseconds. Bu, bir unix zaman damgası döndürür.

Uygulamanızda tarihi nasıl görüntülemek istersiniz? Bir tarih nesnesi almak istiyorsanız, zaman damgasını böyle bir tarih yapıcısına geçirebilirsiniz new Date(user.createdAt.nanoseconds). Şahsen date-fns kütüphanesini işlemek için kullanmaktan zevk alıyorum .


Teşekkürler - Bu öneriyi denedim. Şu hatayı döndürür: TypeError: undefined öğesinin 'nanosaniye' özelliği okunamıyor. Şimdi önerdiğiniz kütüphaneye bir göz
Mel

Lütfen giriş yapın ve paylaşın. Verilerin zaman uyumsuz doğası göz önüne alındığında, büyük olasılıkla veriyi böyle döndürmeniz gerekir user.createdAt && new Date(user.createdAt.nanoseconds). Date-fns bu soruna yardımcı olmaz, sadece bir kez sahip olduğunuzda tarihi görüntülemek için kullanışlı bir kütüphane.
Josh Pittman

createdAt açılır menülerin uzun bir listesini günlüğe kaydeder. Firestore'daki alanda gösterilen tarihi içeren birini bulamıyorum. İlk kısım: createdAt: ServerTimestampFieldValueImpl _methodName: "FieldValue.serverTimestamp" proto : FieldValueImpl yapıcı: ƒ ServerTimestampFieldValueImpl () örneği: ServerTimestampFieldValueImpl _methodName: "FieldValue.serverTimestamp" proto : FieldValueImpl yapıcı: ServerTimestampFieldValueImpl ƒ () örneği: ServerTimestampFieldValueImpl {_methodName: " FieldValue.serverTimestamp "} argümanları: (...) arayan: (...)
Mel

Gerçek bir zaman damgası değil, zaman damgası işlevini veritabanına aktardığınız anlaşılıyor. Zaman damgasını nasıl ayarlıyorsunuz? firestore.FieldValue.serverTimestamp()
Josh Pittman

Firestore'da gösterilen girdi eklediğim fotoğraf. Bu giriş: this.props.firebase.fieldValue.serverTimestamp ()
Mel

2

Firestore'a tarih nasıl gönderilir:

import firebase from 'firebase/app';

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

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

Geri nasıl okunur:

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

Temelde createdAt.toDate()bir JS Date nesnesi alırsınız.

Her zaman böyle kullanıyorum!

Gönderen: https://cloud.google.com/firestore/docs/manage-data/add-data

resim açıklamasını buraya girin

Bu, kullanıcının sistem tarihine göre bir veri oluşturur. DB'nizde her şeyin kronolojik olarak saklanacağından emin olmanız gerekiyorsa (kullanıcı sisteminiz tarafından ayarlanan yanlış sistem tarihlerinde herhangi bir hata olmadan), bir sunucu zaman damgası kullanmalısınız. Tarih, Firestore DB dahili tarih sisteminiz kullanılarak ayarlanır.

resim açıklamasını buraya girin


Bunun için teşekkürler, ama üstesinden gelmeye çalıştığım sorun, veritabanına kaydedilen tarihi görüntülemek için bir yol bulamıyorum. Paylaştığım türden hatalar alıyorum.
Mel

2

createdAtÖzelliği ayarlanmış bir Kullanıcının belge kimliğiyle aşağıdakileri deneyin:

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

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

Belgenin .data()özelliklerine erişmeden önce yöntemi çağırmak önemlidir

Özelliğinin ayarlanmadığı docRef.data().createdAt.toDate()bir kullanıcıya erişirseniz ,createdAtTypeError: Cannot read property 'toDate' of undefined

Yani koleksiyonunuzda createdAttanımlanmış özelliği olmayan herhangi bir kullanıcınız olması durumunda . Kullanmadan createdAtönce kullanıcının mülke sahip olup olmadığını kontrol etmek için bir mantık uygulamalısınız . Bunun gibi bir şey yapabilirsiniz:

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

Yukarıda da görebileceğiniz gibi, belge alanlarına yönelik isteklerde data () kullanıyorum. Eğer olmasaydım diğer alanlar oluşturmazdı. Belirli sorun, oluşturulmayan zaman damgasıyla ilgilidir. Yukarıda yaptığım ve yukarıda belirlediğim girişimlerden biri, toDate () uzantısını kullanma girişimini içeriyor. Çalışmıyor - yukarıda belirtilen nedenlerden dolayı. Yine de zaman ayırdığınız için teşekkürler.
Mel

0

Ben iç içe nesne özellikleri listelerinde düzgün şekilde oluşturulmaması ile geçmişte sorun yaşadığınızı item.somePropbir nesne olarak kabul edilir, fakat item.someProp.someSubPropdeğeriyle çözmez someSubPropiçinde item.someProp.

Bu nedenle, sorunu çözmek için, kullanıcı nesnesini oluştururken neden Zaman Damgası'nı düz bir tarih nesnesine (veya istenen görüntüleme biçimine) değerlendirmiyorsunuz?

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

Ayrıca her ikisine de dikkat etmek DocumentSnapshot#data()ve DocumentSnapshot#get()henüz kesinleştirilmemiş FieldValue.serverTimestamp()değerlerin nasıl işleneceğini belirten bir nesneyi kabul etmek gerekir . Varsayılan olarak, henüz sonlandırılmamış bir değer boş olacaktır. Kullanmak { serverTimestamps: "estimate"}, bu boş değerleri bir tahmine dönüştürür.
samthecodingman

Merhaba - öneri için teşekkürler. Denemek istiyorum ama anlamıyorum - ya da nasıl uygulamayı deneyebilirim. Bu öneriyi sunarken uyguladığınız ilkeler için bir sözleşme var mı? Yaklaşım hakkında literatür bulabilirsem, fikrimin nasıl çalıştığını anlamaya çalışacağım, böylece benim kodumda deneyebilirim.
Mel

Yıllar boyunca diğer StackOverflow sorularına baktıktan sonra aldığım için bunun için belirli bir kaynağım yok .
samthecodingman

Paylaşım için teşekkürler. Bunları bu gece okuyacağım
Mel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.