如何使用 Firebase "onSnapshot" 侦听器值更新 Vue "ref"?

How to update a Vue "ref" with Firebase "onSnapshot" listener values?

我有一个使用 Firebase onSnapshot 侦听器的 Vue 可组合项。

当该侦听器上的数据更改时,我希望它更新名为 documentsArrayref

当我在 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})