Attendi fino a quando Firebase ha terminato il caricamento dei dati (vue) / "Attendere" non funziona
Nella mia app vue, sto recuperando alcuni dati da Firebase nel created
-hook. Voglio che il codice venga eseguito successivamente al termine del caricamento dei dati. Ma non riesco a farlo funzionare.
Ecco il mio codice:
<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>
Ma prima 'Done with fetching Data'
viene visualizzata la console, poi null
(perché this.settings
è ferma null
) e solo dopo settings
viene stampato l'Oggetto . Ma ho bisogno this.settings
di essere definito lì (e non null
più) per lavorarci.
Quello che ho provato finora:
- Mettere in attesa
- Aggiunta di un file
parameter
- Aggiungendo il codice in seguito in un file
then()
Niente ha funzionato.
Risposte
Il onSnapshot()metodo non è un metodo asincrono. Come spiegato nel documento, "allega un listener per gli DocumentSnapshot
eventi".
Quindi, dovresti usarlo se vuoi impostare un ascoltatore continuo al documento Firestore: se qualcosa cambia nel documento (ad esempio un campo riceve un nuovo valore) il listener verrà attivato. Notare che "una chiamata iniziale utilizzando il callback fornito crea immediatamente un'istantanea del documento con il contenuto corrente del singolo documento" (vedere il documento ).
Ottieni i dati del documento Firestore solo nella funzione di callback a cui passi onSnapshot()
, come segue:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
Come accennato da Nilesh Patel, tieni presente che devi utilizzare una funzione freccia per thispoterla utilizzare in questo callback . Si noti inoltre che la created
funzione NON deve essere asincrona .
Infine, onSnapshot()
tieni presente che è una buona pratica chiamare la funzione di annullamento dell'iscrizione restituita da quando distruggi il componente Vue.js. Usa il beforeDestroy
gancio come segue:
// ...
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'altra parte, se si desidera leggere i dati del documento SOLO UNA VOLTA nell'hook Vue.js creato, è necessario utilizzare il get()metodo, come segue:
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!");
}
}
Notare che, in questo caso, la created
funzione DEVE essere async
, poiché get()
è asincrona.
Maggiori dettagli sulla differenza tra get()
e onSnapshot()
in questa risposta SO .
prova a usare la funzione freccia
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)
},