如何使用 Firebase "onSnapshot" 侦听器值更新 Vue "ref"?
How to update a Vue "ref" with Firebase "onSnapshot" listener values?
我有一个使用 Firebase onSnapshot
侦听器的 Vue 可组合项。
当该侦听器上的数据更改时,我希望它更新名为 documentsArray
的 ref
。
当我在 console.log documentsArray
内部 onSnapshot
函数时,它似乎可以正常工作,因为它包含一个值数组。但是当我 console.log 在 之外时 onSnapshot
函数数组是空的。
为什么会这样?
console.log在之外onSnapshot
函数也应该包含值数组。
这是我的可组合项(我使用的是 TypeScript):
import { ref, Ref, watchEffect } from "vue";
import { projectFirestore } from "@/firebase/config";
import {
collection,
query,
orderBy,
onSnapshot,
DocumentData,
Timestamp,
} from "firebase/firestore";
interface Document {
id: string;
message: string;
name: string;
createdAt: Timestamp;
}
const getCollection = (
collectionString: string
): {
documentsArray: Ref<Document[] | null>;
error: Ref<string | null>;
} => {
const documentsArray = ref<Document[] | null>(null);
const error = ref<string | null>(null);
const colRef = collection(projectFirestore, collectionString);
const colRefOrdered = query(colRef, orderBy("createdAt"));
const unsubscribe = onSnapshot(
colRefOrdered,
(snap) => {
const results: Document[] = [];
snap.docs.forEach((doc: DocumentData) => {
doc.data().createdAt && //Ensures the server timestamp has been added
results.push({
...doc.data(),
id: doc.id,
});
});
documentsArray.value = results;
console.log("documentsArray.value inside snapshot", documentsArray.value); //<-- This works. It prints an array of documents.
error.value = null;
},
(err) => {
console.log(err.message);
documentsArray.value = null;
error.value = "could not fetch data";
}
);
watchEffect((onInvalidate) => {
onInvalidate(() => {
unsubscribe();
});
});
console.log("documentsArray.value outside snapshot", documentsArray.value); //<-- This does not work. It prints an empty array.
return { documentsArray, error };
};
export default getCollection;
onSnapshot
回调内的代码是 运行 异步的(在 运行 调用回调外的代码之后),以便查看您必须创建的外部函数的更改观察者看到变化:
import import { ref, Ref, watchEffect, watch } from "vue";
....
const unsubscribe = onSnapshot(
colRefOrdered,
(snap) => {
...
);
watch(documentsArray,(newVal,oldVal){
console.log("documentsArray.value outside snapshot", documentsArray.value);
},{deep:true})
我有一个使用 Firebase onSnapshot
侦听器的 Vue 可组合项。
当该侦听器上的数据更改时,我希望它更新名为 documentsArray
的 ref
。
当我在 console.log documentsArray
内部 onSnapshot
函数时,它似乎可以正常工作,因为它包含一个值数组。但是当我 console.log 在 之外时 onSnapshot
函数数组是空的。
为什么会这样?
console.log在之外onSnapshot
函数也应该包含值数组。
这是我的可组合项(我使用的是 TypeScript):
import { ref, Ref, watchEffect } from "vue";
import { projectFirestore } from "@/firebase/config";
import {
collection,
query,
orderBy,
onSnapshot,
DocumentData,
Timestamp,
} from "firebase/firestore";
interface Document {
id: string;
message: string;
name: string;
createdAt: Timestamp;
}
const getCollection = (
collectionString: string
): {
documentsArray: Ref<Document[] | null>;
error: Ref<string | null>;
} => {
const documentsArray = ref<Document[] | null>(null);
const error = ref<string | null>(null);
const colRef = collection(projectFirestore, collectionString);
const colRefOrdered = query(colRef, orderBy("createdAt"));
const unsubscribe = onSnapshot(
colRefOrdered,
(snap) => {
const results: Document[] = [];
snap.docs.forEach((doc: DocumentData) => {
doc.data().createdAt && //Ensures the server timestamp has been added
results.push({
...doc.data(),
id: doc.id,
});
});
documentsArray.value = results;
console.log("documentsArray.value inside snapshot", documentsArray.value); //<-- This works. It prints an array of documents.
error.value = null;
},
(err) => {
console.log(err.message);
documentsArray.value = null;
error.value = "could not fetch data";
}
);
watchEffect((onInvalidate) => {
onInvalidate(() => {
unsubscribe();
});
});
console.log("documentsArray.value outside snapshot", documentsArray.value); //<-- This does not work. It prints an empty array.
return { documentsArray, error };
};
export default getCollection;
onSnapshot
回调内的代码是 运行 异步的(在 运行 调用回调外的代码之后),以便查看您必须创建的外部函数的更改观察者看到变化:
import import { ref, Ref, watchEffect, watch } from "vue";
....
const unsubscribe = onSnapshot(
colRefOrdered,
(snap) => {
...
);
watch(documentsArray,(newVal,oldVal){
console.log("documentsArray.value outside snapshot", documentsArray.value);
},{deep:true})