Warten Sie, bis die Firebase das Laden der Daten beendet hat (vue) / 'Warten' funktioniert nicht mehr
In meiner Vue-App created
rufe ich einige Daten aus der Firebase im -hook ab. Ich möchte, dass der Code danach ausgeführt wird, nachdem die Daten mit dem Laden fertig sind. Aber ich kann es nicht zum Laufen bringen.
Hier ist mein Code:
<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>
Aber zuerst 'Done with fetching Data'
wird die Konsole angezeigt, dann null
(weil this.settings
noch null
) und erst danach wird das Objekt settings
gedruckt. Aber ich muss this.settings
dort definiert werden (und nicht null
mehr), um dort zu arbeiten.
Was ich bisher versucht habe:
- Das Einsetzen wartet
- Hinzufügen eines geladenen
parameter
- Fügen Sie den Code anschließend in a
then()
Nichts hat geklappt.
Antworten
Die onSnapshot()Methode ist keine asynchrone Methode. Wie im Dokument erläutert, wird "ein Listener für DocumentSnapshot
Ereignisse angehängt".
Sie sollten es also verwenden, wenn Sie einen kontinuierlichen Listener für das Firestore-Dokument festlegen möchten : Wenn sich im Dokument etwas ändert (z. B. wenn ein Feld einen neuen Wert erhält), wird der Listener ausgelöst. Beachten Sie, dass "ein erster Anruf mit dem von Ihnen bereitgestellten Rückruf sofort einen Dokumentschnappschuss mit dem aktuellen Inhalt des einzelnen Dokuments erstellt" (siehe Dokument ).
Sie erhalten die Firestore-Dokumentdaten nur in der Rückruffunktion, an die Sie onSnapshot()
wie folgt übergeben:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
Beachten Siethis , dass Sie, wie von Nilesh Patel erwähnt, eine Pfeilfunktion verwenden müssen, um diesen Rückruf verwenden zu können . Beachten Sie auch, dass die created
Funktion NICHT asynchron sein muss .
Beachten Sie schließlich, dass es empfehlenswert ist, die Funktion zum Abbestellen aufzurufen, die zurückgegeben wird, onSnapshot()
wenn Sie die Komponente Vue.js zerstören. Verwenden Sie den beforeDestroy
Haken wie folgt:
// ...
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();
}
},
Wenn Sie die Dokumentdaten jedoch NUR EINMAL im erstellten Vue.js-Hook lesen möchten , sollten Sie die folgende get()Methode verwenden:
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!");
}
}
Beachten Sie, dass in diesem Fall die created
Funktion sein muss async
, da sie get()
asynchron ist.
Weitere Details zum Unterschied zwischen get()
und onSnapshot()
in dieser SO-Antwort .
Versuchen Sie es mit der Pfeilfunktion
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)
},