Firebaseがデータの読み込みを完了するまで待つ(vue)/ 'await'が機能しない

Jan 11 2021

私の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>

ただし、コンソールの1つは、最初'Done with fetching Data'に表示され、次にnullthis.settingsまだ表示されているためnull)、その後にのみオブジェクトsettingsが印刷されます。しかし、そこで作業するには、そこでthis.settings定義する必要があります(nullもう定義する必要はありません)。

私がこれまでに試したこと:

  1. 入れて待つ
  2. ロードされたものを追加する parameter
  3. 後でコードを追加する then()

何も機能しませんでした。

回答

3 RenaudTarnec Jan 11 2021 at 00:56

このonSnapshot()メソッドは非同期メソッドではありません。ドキュメントで説明されているように、「DocumentSnapshotイベントのリスナーをアタッチします」。

したがって、Firestoreドキュメントに継続的なリスナー設定する場合は、これを使用する必要があります。ドキュメント内で何かが変更された場合(たとえば、フィールドが新しい値を取得した場合)、リスナーがトリガーされます。「指定したコールバックを使用した最初の呼び出しで、単一のドキュメントの現在のコンテンツを含むドキュメントスナップショットがすぐに作成される」ことに注意してください(ドキュメントを参照)。

次のように、Firestoreドキュメントデータは、渡すコールバック関数でのみ取得さonSnapshot()れます。

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

Nilesh Patelが述べたように、このコールバックで使用するには、矢印関数を使用する必要がthisあることに注意してください。また、created関数は非同期である必要はないことに注意してください。

最後に、onSnapshot()Vue.jsコンポーネントを破棄したときに返される購読解除関数を呼び出すことをお勧めします。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フックに、あなたが使うべき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()


このSO回答のget()との違いの詳細。onSnapshot()

1 NileshPatel Jan 11 2021 at 00:46

矢印機能を使ってみてください

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