Chờ cho đến khi firebase tải xong dữ liệu (vue) / 'await' không hoạt động
Trong ứng dụng vue của mình, tôi đang tìm nạp một số dữ liệu từ firebase trong created
-hook. Tôi muốn mã sau đó được xuất hiện sau khi dữ liệu được tải xong. Nhưng tôi không thể làm cho nó hoạt động.
Đây là mã của tôi:
<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>
Nhưng một bảng điều khiển, đầu tiên 'Done with fetching Data'
được hiển thị, sau đó null
(bởi vì this.settings
vẫn còn null
) và chỉ sau đó objekt settings
được in. Nhưng tôi cần this.settings
phải được xác định ở đó (và không null
nữa) để làm việc với đó.
Những gì tôi đã thử cho đến nay:
- Đang chờ đợi
- Thêm một tải
parameter
- Thêm mã sau đó trong một
then()
Không có gì hoạt động.
Trả lời
Các onSnapshot()phương pháp không phải là một phương pháp không đồng bộ. Như đã giải thích trong tài liệu, nó "đính kèm một trình lắng nghe cho DocumentSnapshot
các sự kiện".
Vì vậy, bạn nên sử dụng nó nếu bạn muốn thiết lập một trình nghe liên tục cho tài liệu Firestore: nếu có điều gì đó thay đổi trong tài liệu (ví dụ: một trường nhận giá trị mới) thì trình nghe sẽ được kích hoạt. Lưu ý rằng "lệnh gọi ban đầu sử dụng lệnh gọi lại mà bạn cung cấp sẽ tạo ảnh chụp nhanh tài liệu ngay lập tức với nội dung hiện tại của tài liệu đơn lẻ" (xem tài liệu ).
Bạn chỉ nhận được dữ liệu tài liệu Firestore trong hàm gọi lại mà bạn chuyển đến onSnapshot()
, như sau:
created() {
institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
this.settings = doc.data();
console.log(this.settings);
});
}
Như Nilesh Patel đã đề cập, lưu ý rằng bạn cần sử dụng hàm mũi tên để sử dụng thistrong lệnh gọi lại này . Cũng lưu ý rằng created
hàm KHÔNG cần phải async .
Cuối cùng, lưu ý rằng bạn nên gọi hàm hủy đăng ký được trả về onSnapshot()
khi bạn hủy thành phần Vue.js. Sử dụng beforeDestroy
móc như sau:
// ...
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();
}
},
Mặt khác, nếu bạn chỉ muốn đọc dữ liệu tài liệu CHỈ MỘT LẦN trong hook Vue.js đã tạo, bạn nên sử dụng get()phương pháp như sau:
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!");
}
}
Lưu ý rằng, trong trường hợp này, created
hàm CẦN phải trở thành async
, vì get()
là không đồng bộ.
Thêm chi tiết về sự khác biệt giữa get()
và onSnapshot()
trong câu trả lời SO này .
thử sử dụng chức năng mũi tên
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)
},