【问题标题】:Wait until firebase has finished loading data (vue) / 'await' not working等到firebase完成加载数据(vue)/'await'不起作用
【发布时间】:2021-04-15 18:39:52
【问题描述】:

在我的 vue 应用程序中,我从 created-hook 中的 firebase 获取一些数据。 我希望在数据加载完成后执行代码。但我不能让它工作。

这是我的代码:

<template>
    <div>
        <h1>Test 2</h1>
    </div>
</template>

<script>
import { institutesCollection } from '../firebase';
export default {
    name: 'Test2',
    data() {
        return {
            settings: null,
        }
    },
    async created() {
        await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(
            await function(doc) {
                this.settings = doc.data();
                console.log(this.settings);
            }
        )
        console.log('Done with fetching Data');
        console.log(this.settings)
    },
    methods: {
        
    }
}
</script>

但是在控制台中,首先显示'Done with fetching Data',然后显示null(因为this.settings 仍然是null),然后才打印Objekt settings。 但我需要在那里定义this.settings(不再是null)才能在那里工作。

到目前为止我尝试了什么:

  1. 等待加入
  2. 添加已加载的parameter
  3. 之后在then() 中添加代码

没有任何效果。

【问题讨论】:

    标签: javascript firebase vue.js google-cloud-firestore vuejs2


    【解决方案1】:

    尝试使用箭头函数

      async created() {
            await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(
                doc => {
                    this.settings = doc.data();
                    console.log(this.settings);
                }
            )
            console.log('Done with fetching Data');
            console.log(this.settings)
      },
    

    【讨论】:

      【解决方案2】:

      onSnapshot() 方法不是异步方法。正如文档中所解释的,它“为DocumentSnapshot 事件附加了一个侦听器”。

      因此,如果您想为 Firestore 文档设置一个连续的侦听器,则应该使用它:如果文档中的某些内容发生了变化(例如,某个字段获得了新值),则将触发侦听器。请注意,“使用您提供的回调的初始调用会立即使用单个文档的当前内容创建文档快照”(请参阅​​doc)。

      您仅在传递给onSnapshot() 的回调函数中获取Firestore 文档数据,如下所示:

      created() {
          institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
                 this.settings = doc.data();
                 console.log(this.settings);
            });
      }
      

      正如 Nilesh Patel 提到的,请注意 you need to use an arrow function in order to use this in this callback。另请注意,created 函数不需要异步

      最后,请注意,在销毁 Vue.js 组件时调用 onSnapshot() 返回的取消订阅函数是一个好习惯。使用beforeDestroy钩子如下:

      // ...
      data() {
          return {
              settings: null,
              firestoreListener: null
          }
      },
      created() {
          this.firestoreListener  = institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
                 this.settings = doc.data();
                 console.log(this.settings);
            });
      },
      beforeDestroy() {
        if (this.firestoreListener) {
          this.firestoreListener();
        }
      },
      

      另一方面,如果你只想在创建的 Vue.js 钩子中读取文档数据ONLY ONCE,你应该使用get() 方法,如下:

      async created() {
          const doc = await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').get();
          if (doc.exists) {
                   this.settings = doc.data();
          } else {
                   // doc.data() will be undefined in this case
                   console.log("No such document!");
          }
      }
      

      请注意,在这种情况下,created 函数需要async,因为get() 是异步的。


      更多关于get()onSnapshot()区别的细节在这个SO answer中。

      【讨论】:

      • 我不知道!谢谢,解决了我的问题
      猜你喜欢
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 2015-01-28
      • 2019-01-30
      • 2018-11-16
      • 1970-01-01
      • 2018-09-23
      相关资源
      最近更新 更多