Attendez que Firebase ait fini de charger les données (vue) / 'await' ne fonctionne pas
Dans mon application vue, je récupère des données de Firebase dans le created
-hook. Je veux que le code soit exécuté après la fin du chargement des données. Mais je ne peux pas le faire fonctionner.
Voici mon 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>
Mais une console, d'abord 'Done with fetching Data'
est affichée, puis null
(parce qu'elle this.settings
est toujours null
) et seulement après que l'Objekt settings
est imprimé. Mais j'ai besoin this.settings
d'être défini là-bas (et plus null
maintenant) pour travailler avec là-bas.
Ce que j'ai essayé jusqu'à présent:
- La mise en attend
- Ajout d'un chargé
parameter
- Ajout du code par la suite dans un
then()
Rien n'a fonctionné.
Réponses
La onSnapshot()méthode n'est pas une méthode asynchrone. Comme expliqué dans le doc, il "attache un écouteur pour les DocumentSnapshot
événements".
Donc, vous devriez l'utiliser si vous voulez définir un écouteur continu pour le document Firestore: si quelque chose change dans le document (par exemple un champ obtient une nouvelle valeur), l'écouteur sera déclenché. Notez que "un appel initial utilisant le rappel que vous fournissez crée immédiatement un instantané de document avec le contenu actuel du document unique" (voir le document ).
Vous obtenez les données du document Firestore uniquement dans la fonction de rappel à laquelle vous passez onSnapshot()
, comme suit:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
Comme Nilesh Patel l'a mentionné, notez que vous devez utiliser une fonction de flèche pour pouvoir l'utiliser thisdans ce rappel . Notez également que la created
fonction n'a PAS besoin d'être asynchrone .
Enfin, notez qu'il est onSnapshot()
recommandé d'appeler la fonction de désabonnement renvoyée par lorsque vous détruisez le composant Vue.js. Utilisez le beforeDestroy
crochet comme suit:
// ...
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();
}
},
D'autre part, si vous souhaitez simplement lire les données du document UNE SEULE FOIS dans le hook Vue.js créé, vous devez utiliser la get()méthode, comme suit:
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!");
}
}
Notez que, dans ce cas, la created
fonction DOIT être async
, car elle get()
est asynchrone.
Plus de détails sur la différence entre get()
et onSnapshot()
dans cette réponse SO .
essayez d'utiliser la fonction fléchée
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)
},