reactjs - 在 useEffect React 中调用异步函数中的 Firebase v9 onSnapShot

标签 reactjs firebase firebase-realtime-database react-hooks google-cloud-functions

我正在使用 Firebase v9,正在构建一个聊天应用,我需要在调用 onSnapShot 获取聊天数据之前执行一些异步工作:

      const getChat = async () => {
        // I need to await for user data before doing anything else.
        // I'll need some user data to build the query which
        // I'll be using in onSnapShot later on.
        const user = await getUserData();
        console.log(user);
        
        const collectionRef = collection(db, "messages");
        const q = query(
        collectionRef, where("user_id", "==", user.id), orderBy("createdAt"));
    
        const unsubscribe = onSnapshot(q, (snapshot) => {
          const data = snapshot.docs.map((doc) => {
            const entry = doc.data();
    
            return {
              id: doc.id,
              message: entry.message,
            };
          });
          setChatLines(data);
        });
    
        return unsubscribe;
      };

然后在useEffect中:

  useEffect(() => {

    const unsubscribe = getChat();

    return () => {
      unsubscribe();
    };
  }, []);

这里的问题是 unsubsribe 是一个 promise ,因为 getChat 是异步的,但我仍然想在 onSnapShot 之前等待 getUserData()被调用,因为稍后我将在 onSnapShot 查询中需要用户数据。

有没有办法让这项工作同时能够在 useEffect 清理函数中正确取消订阅

最佳答案

在这种情况下,我建议使用 React ref 来保存要在 useEffect 清理函数中使用的取消订阅函数。

const unsubscribeRef = React.useRef();

const getChat = async () => {
  const user = await getUserData();
   
  const collectionRef = collection(db, "messages");
  const q = query(
  collectionRef, where("user_id", "==", user.id), orderBy("createdAt"));

  const unsubscribe = onSnapshot(q, (snapshot) => {
    const data = snapshot.docs.map((doc) => {
      const entry = doc.data();

      return {
        id: doc.id,
        message: entry.message,
      };
    });
    setChatLines(data);
  });

  unsubscribeRef.current = unsubscribe;
};

useEffect(() => {
  getChat();

  return () => {
    unsubscribeRef.current?.();
  };
}, []);

另一种选择是在 useEffect Hook 回调主体中添加一个额外的异步函数,该函数可以等待 getChat Promise 解析。

useEffect(() => {
  let unsubscribe;

  const getChatAndSubscribe = async () => {
    unsubscribe = await getChat();
  }
    
  getChatAndSubscribe();

  return () => {
    unsubscribe?.();
  };
}, []);

关于reactjs - 在 useEffect React 中调用异步函数中的 Firebase v9 onSnapShot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69732710/

相关文章:

ios - Firebase 性能监控如何拦截 iOS 中的传出 http 请求?

javascript - 顶部带有箭头的 React 水平滚动卡片

node.js - React Js 中的重定向

ios - 由于 Firebase GoogleService-Info.plist,Codemagic iOS 构建失败

ios - Firebase CocoaPods 太大 (70mb)

javascript - 无法在 firebase 上上传数据?

javascript - 如何限制用户在 firebase 实时数据库中每 15 分钟写一次帖子

android - 数据库调用后如何设置文本

javascript - BlueprintJS/React - 通过 onClick 检索 TagInput > 标签值时遇到问题

javascript - 如何根据 obj 标志的状态查找数组长度