【问题标题】:Firestore took too long to fetch data therefore I couldn't display itFirestore 获取数据的时间太长,因此我无法显示它
【发布时间】:2020-03-19 14:01:00
【问题描述】:

我有一个从 Firestore 获取数据的函数:

  getLastTime(collectionName: string) {
    const docRef = this.afs.firestore.collection(collectionName).doc(this.User).collection('lastTime').doc('lastTime');
    docRef.get().then(doc => {
      if (doc.exists) {
          this.get = doc.data().lastTime;
      } else {
          this.get = 'Never done';
      }
  }).catch(error => {
      console.log('Error getting document:', error);
  });
    return this.get;
  }

对于我的测试,我实际上在文档“lastTime”中有一个字符串值,它是一个字符串。

在 ngOnInit() 中,我调用了我的函数并 console.log 记录了结果

this.InjuredLastTime = this.getLastTime('INJURY');
console.log(this. this.InjuredLastTime);

通常我应该在控制台中打印我的字符串,但我没有定义......

也许是因为 Firestore 没有足够快地获取我的数据,但我很惊讶,因为 Firestore 正常速度很快......

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    在从getLastTime() 返回之前,您实际上并没有等待docRef.get() 创建的承诺。因此,除非对 firebase 的调用是即时的(例如从不),否则这是行不通的。

    正确的解决方案实际上取决于您对this.InjuredLastTime 所做的事情。但一种方法是返回一个 Promise 并在它准备好后设置它:

    getLastTime(collectionName: string) {
        const docRef = this.afs.firestore.collection(collectionName).doc(this.User).collection('lastTime').doc('lastTime');
        return docRef.get().then(doc => {
          if (doc.exists) {
              return doc.data().lastTime;
          } else {
              return 'Never done';
          }
        }).catch(error => {
          console.log('Error getting document:', error);
          return null;
        });
    }
    

    然后,不是同步分配,而是异步执行:

    this.getLastTime('INJURY').then(result => { this.InjuredLastTime = result });
    

    【讨论】:

      【解决方案2】:

      数据是从 Firestore 异步加载的,因为数据从服务器返回之前可能需要一些时间。为了避免阻塞浏览器,您的代码可以继续运行,然后在数据可用时调用您的回调。

      您可以通过一些放置良好的日志语句轻松地看到这一点:

      const docRef = this.afs.firestore.collection(collectionName).doc(this.User).collection('lastTime').doc('lastTime');
      console.log('Before starting to get data');
      docRef.get().then(doc => {
        console.log('Got data');
      });
      console.log('After starting to get data');
      

      如果你运行这段代码,你会得到:

      开始获取数据之前

      开始获取数据后

      得到数据

      这可能不是您期望的日志输出顺序,但它实际上是正确的行为。它完全解释了为什么您要从 getLastTime 函数中得到 undefined:当 return this.get; 运行时,数据还没有加载。

      现代 JavaScript 中最简单的解决方案是将您的函数标记为 async,然后将其结果标记为 await。看起来像这样:

      async function getLastTime(collectionName: string) {
          const docRef = this.afs.firestore.collection(collectionName).doc(this.User).collection('lastTime').doc('lastTime');
          doc = await docRef.get();
          if (doc.exists) {
              this.get = doc.data().lastTime;
          } else {
              this.get = 'Never done';
          }
          return this.get;
      }
      

      然后调用它:

      this.InjuredLastTime = await this.getLastTime('INJURY');
      

      【讨论】:

        猜你喜欢
        • 2017-12-20
        • 2019-12-26
        • 1970-01-01
        • 2019-06-10
        • 1970-01-01
        • 2022-10-15
        • 1970-01-01
        • 1970-01-01
        • 2018-05-27
        相关资源
        最近更新 更多