Poczekaj, aż Firebase zakończy ładowanie danych (vue) / 'await' nie działa
W mojej aplikacji vue created
pobieram dane z Firebase w -hook. Chcę, aby kod był później wykonywany po zakończeniu ładowania danych. Ale nie mogę sprawić, żeby to zadziałało.
Oto mój kod:
<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>
Ale najpierw konsola 'Done with fetching Data'
jest wyświetlana, potem null
(ponieważ this.settings
jest nieruchoma null
) i dopiero potem settings
drukowany jest Objekt . Ale muszę this.settings
być tam zdefiniowany (i null
już nie ), aby tam pracować.
Co próbowałem do tej pory:
- Wstawianie czeka
- Dodanie załadowanego pliku
parameter
- Dodanie kodu później w pliku
then()
Nic nie działało.
Odpowiedzi
onSnapshot()Metoda nie jest metodą asynchroniczny. Jak wyjaśniono w dokumencie, „dołącza nasłuchiwanie DocumentSnapshot
zdarzeń”.
Dlatego powinieneś go użyć, jeśli chcesz ustawić ciągły nasłuchiwanie dokumentu Firestore: jeśli coś się zmieni w dokumencie (np. Pole otrzyma nową wartość), detektor zostanie wyzwolony. Zwróć uwagę, że „pierwsze połączenie przy użyciu dostarczonego przez Ciebie wywołania zwrotnego tworzy natychmiast migawkę dokumentu z bieżącą zawartością pojedynczego dokumentu” (zobacz dokumentację ).
Dane dokumentu Firestore uzyskujesz tylko w funkcji wywołania zwrotnego, do której przekazujesz onSnapshot()
, w następujący sposób:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
Jak wspomniał Nilesh Patel, pamiętaj, że musisz użyć funkcji strzałki, aby użyć thistego wywołania zwrotnego . Należy również pamiętać, że created
funkcja NIE musi być asynchroniczna .
Na koniec zwróć uwagę, że dobrą praktyką jest wywołanie funkcji anulowania subskrypcji zwracanej onSnapshot()
po zniszczeniu komponentu Vue.js. Użyj beforeDestroy
haka w następujący sposób:
// ...
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();
}
},
Z drugiej strony, jeśli chcesz po prostu odczytać dane dokumentu TYLKO RAZ w utworzonym hooku Vue.js, powinieneś użyć następującej get()metody:
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!");
}
}
Zauważ, że w tym przypadku created
funkcja MUSI być async
, ponieważ get()
jest asynchroniczna.
Więcej szczegółów na temat różnicy między get()
iw onSnapshot()
tej odpowiedzi TAK .
spróbuj użyć funkcji strzałek
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)
},