【问题标题】:Firestore, onSnapshot() or async/await issue or bothFirestore、onSnapshot() 或 async/await 问题或两者兼有
【发布时间】:2021-02-07 19:15:58
【问题描述】:

我正在尝试使用 Firebase Firestore 的 onShapshot() 进行一系列更改。

我无法通过onSnapshot() 检索数据;我可能对async/await 也有麻烦,不太确定...

你能看出哪里有问题吗?

输出应该是(但目前是):

1. New friends: ... // via onSnapshot(). Should not be empty, but it is (However, it does get populated afterwards).
2. All friends: ... // Should not be empty, but it is.
3. Fred's friends: ... // Should not be empty, but it is.

代码:

const getAllFriends = async () => {
    // Gets all friends by connecting to Firestore's onSnapshot stream.

    const getNewFriends = async () => {
        // Sets up a onSnapshot() stream, and returns a newFriends array with their names.
        // Problem: It initially return an empty array, when it shouldn't be empty.

        let newFriends = [];
        await db.collection("user").doc("john").collection("friends").onSnapshot(snapshot => {
            snapshot.docChanges().forEach(change => {
                newFriends.push({ friend: "Emily" });
            });
        });

        console.log("1. New friends: ", newFriends, newFriends.length); // Length should not be 0.
        return newFriends;
    }

    // John starts with no friends:
    let friends = []; 

    // John should now have found some friends:
    let friendChanges = await getNewFriends(); 
    friends = friends.concat(friendChanges);

    console.log("2. All friends:", friends); // Should contain a few Emilys.
    return friends;
};

let johnFriends = await getAllFriends();
console.log("3. John's friends:", friends); // Should contain a few Emilys.

【问题讨论】:

  • 如果您只需要检索数据,则不要使用 onSnapshot() 函数,而是使用 .get() 方法,那么异步等待可能会起作用。
  • 您找到这个问题的答案了吗?我似乎遇到了类似的问题。

标签: javascript firebase google-cloud-firestore


【解决方案1】:

看看这个answer,它解释了get()onSnapshot()方法之间的区别。

简而言之:

  • 当您使用 get() 时,您只检索一次集合中的所有文档(如“获取并忘记”)。
  • 当您使用 onSnapshot() 时,您会不断收听合集。

注意onSnapshot() 不是异步方法,而get() 是=> 不要用await 调用onSnapshot()


由于您的问题,您似乎想通过调用getAllFriends()方法获取好友列表,请执行以下操作:

  const getAllFriends = async (userName) => {
    const querySnapshot = await db
      .collection('user')
      .doc(userName)
      .collection('friends')
      .get();
    return querySnapshot;
  };

  let johnFriends = await getAllFriends('john');
  johnFriends.forEach(doc => {
    console.log(doc.id, ' => ', doc.data());
  });

在 Firestore 文档 herehere 中可以找到更多可能性。

【讨论】:

  • 感谢@Renaud,我可以使用 get() 但这只会获取一次数据(?);我想设置一个监听器(因此想使用 onSnapshot())。我想我必须以另一种方式迭代friendChanges...
  • 你能解释一下你的确切目标是什么吗?您可以很好地为collection("user").doc("john").collection("friends")collection 设置一个侦听器。但请注意,如果您需要收听collection("user").doc("Emily").collection("friends"),则需要设置另一个侦听器。如果您需要收听所有朋友的文件,您应该收听Collection group query,如db.collectionGroup('friends')。告诉我这是否符合您的需求,我会更新答案。
  • 这是应该发生的:当 John 登录时,John 使用来自 db.collection("user").doc("john").collection("friends") 的数据获取一个 HTML 渲染的朋友列表。当 john 添加一个新朋友时,他的 Firestore 朋友集合会更新,他的 HTML 渲染的朋友列表也应该更新(这就是为什么我认为 onSnapshot() 可能是要走的路。我想我最初可以有一个 get()他登录了,还有一个onSnapshot() 来收听以后的变化;很想知道你的想法,谢谢!)。
猜你喜欢
  • 2020-02-23
  • 1970-01-01
  • 2017-11-10
  • 2011-06-17
  • 2011-08-16
  • 2015-10-14
  • 2017-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多