Firebaseがデータの読み込みを完了するまで待つ(vue)/ 'await'が機能しない
私の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'
に表示され、次にnull
(this.settings
まだ表示されているためnull
)、その後にのみオブジェクトsettings
が印刷されます。しかし、そこで作業するには、そこでthis.settings
定義する必要があります(null
もう定義する必要はありません)。
私がこれまでに試したこと:
- 入れて待つ
- ロードされたものを追加する
parameter
- 後でコードを追加する
then()
何も機能しませんでした。
回答
この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()
矢印機能を使ってみてください
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)
},