【问题标题】:Firebase read with react useeffect async not waiting for document readFirebase读取与react useeffect异步不等待文档读取
【发布时间】:2020-07-02 01:12:02
【问题描述】:

我在身份验证上下文中有以下代码 sn-p,我在其中设置登录详细信息以及上下文中的用户特定详细信息。但问题是代码退出了 useEffect 块,即使我使用异步来完成文档读取。但是代码无论如何都会通过 useEffect 并且在那之后检索用户详细信息。

我想在 useEffect 失控之前阅读文档。

请让我知道我做错了什么。

    useEffect(() => {
        auth.onAuthStateChanged(user => {
            let userDetails : IUser = {
                landingPage: "error",
                permissions: {
                    'none' : {
                        'read' : false,
                        'write' : false
                    }
                },
                role: "none",
                shopId: "none"
            };
            if (user) {
                console.log("Read user data now");
                (async function some() {
                    await readDocument("users", user.uid,function (result: IUser) {
                        userDetails = result;
                        console.log("Result received in ", result);
                    });
                })();
            }
            return setState({
                ...authInitialState,
                isAuthenticated: !!user,
                isInitialized: true,
                permissions: userDetails.permissions,
                user: user,
                landingPage: userDetails.landingPage
            });
        });
    }, []);

读取文档函数

function readDocument(collection: string, docId: string, callback: any) {
    console.log("Going to read:", docId);
    db.collection(collection).doc(docId)
        .get()
        .then(function (doc) {
            callback(doc.data());
            console.log("Read data", doc.id, " => ", doc.data());
        })
        .catch(function (error) {
            console.log("Failed to write", error);
        });
}

【问题讨论】:

    标签: reactjs firebase google-cloud-firestore react-hooks


    【解决方案1】:

    我尝试了类似的方法,它奏效了。仍然不是 100% 确定有什么区别。

    const onChange = (user) => {
            console.log("State changed");
            let userDetails: IUser = {
                landingPage: "error",
                permissions: {
                    'none': {
                        'read': false,
                        'write': false
                    }
                },
                role: "none",
                shopId: "none"
            };
    
            if (user) {
                getDocument("users", user.uid)
                    .then(function (result) {
                        userDetails = result.data();
                        setState({
                            ...authInitialState,
                            isAuthenticated: !!user,
                            isInitialized: true,
                            permissions: userDetails.permissions,
                            user: user,
                            landingPage: userDetails.landingPage
                        });
                    });
            }
        }
    
    useEffect(() => {
            auth.onAuthStateChanged((user) => onChange(user));
        }, []);
    

    【讨论】:

      【解决方案2】:

      为了让readDocument 与await 一起工作,它需要一个可以解决的承诺。 https://itnext.io/javascript-promises-and-async-await-as-fast-as-possible-d7c8c8ff0abc - 向下滚动到 async/await 部分

      类似这样的东西(未验证)-

      const readDocument = function (collection: string, docId: string, callback: any) {
        return new Promise((resolve, reject) => {
          db.collection(collection).doc(docId)
              .get()
              .then(function (doc) {
                  resolve(doc.data());
                  console.log("Read data", doc.id, " => ", doc.data());
              })
              .catch(function (error) {
                  console.log("Failed to write", error);
                  reject(error);
              });
        });
      };
      

      【讨论】:

      • readDocument("users", user.uid) .then(function (result) { userDetails = result; console.log("Result received in ", result); }); 和 ``` (async function some() { await readDocument("users", user.uid) .then(function (result) { userDetails = result; console.log("结果在 ", result); }); })(); ``` 不幸的是产生了相同的结果。
      • ``` function readDocument(collection: string, docId: string) { console.log("Going to read:", docId); return new Promise((resolve, reject) => { db.collection(collection).doc(docId) .get() .then(function (doc) { //callback(doc.data()); resolve(doc. data()); console.log("读取数据", doc.id, " => ", doc.data()); }) .catch(function (error) { console.log("写入失败",错误);拒绝(错误);});}); ```
      • 现在你的 useEffect 块只在 componentDidMount 上运行,这是你想要的吗?您可能需要查看某个属性,例如 auth... useEffect(() => { //code// }, [auth]);
      • 我认为即使没有依赖它也会运行一次。我关注了dev.to/spukas/4-ways-to-useeffect-pf6 谢谢。
      猜你喜欢
      • 1970-01-01
      • 2018-04-11
      • 2020-12-03
      • 2018-06-18
      • 2021-09-25
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      相关资源
      最近更新 更多