Aguarde até que o firebase termine de carregar os dados (vue) / 'await' não está funcionando
Em meu aplicativo vue, estou buscando alguns dados do created
firebase no -hook. Eu quero que o código seja executado depois que os dados forem carregados. Mas não consigo fazer funcionar.
Aqui está o meu código:
<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>
Mas um console, primeiro 'Done with fetching Data'
é exibido, depois null
(porque this.settings
ainda está null
) e só depois disso o Objekt settings
é impresso. Mas eu preciso this.settings
ser definido lá (e não null
mais) para trabalhar lá.
O que tentei até agora:
- Colocando em espera
- Adicionando um carregado
parameter
- Adicionando o código posteriormente em um
then()
Nada funcionou.
Respostas
O onSnapshot()método não é um método assíncrono. Conforme explicado no documento, ele "anexa um ouvinte para DocumentSnapshot
eventos".
Portanto, você deve usá-lo se quiser definir um ouvinte contínuo para o documento Firestore: se algo mudar no documento (por exemplo, um campo recebe um novo valor), o ouvinte será acionado. Observe que "uma chamada inicial usando o retorno de chamada que você fornece cria um instantâneo do documento imediatamente com o conteúdo atual do único documento" (consulte o documento ).
Você obtém os dados do documento Firestore apenas na função de retorno de chamada que você passa para onSnapshot()
, da seguinte maneira:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
Como Nilesh Patel mencionou, observe que você precisa usar uma função de seta para usar thisneste retorno de chamada . Observe também que a created
função NÃO precisa ser assíncrona .
Por fim, observe que é uma boa prática chamar a função de cancelamento de assinatura retornada por onSnapshot()
quando você destrói o componente Vue.js. Use o beforeDestroy
gancho da seguinte maneira:
// ...
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();
}
},
Por outro lado, se você deseja apenas ler os dados do documento SOMENTE UMA VEZ no gancho Vue.js criado, você deve usar o get()método da seguinte maneira:
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!");
}
}
Observe que, neste caso, a created
função PRECISA ser async
, pois get()
é assíncrona.
Mais detalhes sobre a diferença entre get()
e onSnapshot()
nesta resposta SO .
tente usar a função de seta
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)
},