Чтение Firebase с реакцией useeffect asyn c не ожидает чтения документа - PullRequest
0 голосов
/ 21 марта 2020

Ниже приведен фрагмент кода в моем контексте аутентификации, в котором я устанавливаю данные для входа в систему с указанием c сведений о пользователе в контексте. Но проблема в том, что код выходит из блока useEffect, хотя я использовал asyn c для завершения чтения документа. Но код все равно проходит мимо 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
            });
        });
    }, []);

Функция readdocument

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);
        });
}

Ответы [ 2 ]

2 голосов
/ 21 марта 2020

Чтобы 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);
        });
  });
};
0 голосов
/ 21 марта 2020

Я попробовал что-то подобное, и это сработало. Еще не уверен на 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));
    }, []);
...