Reputation: 1281
I have below code snippet in my auth context where I set login details along wit user specific details in context. But the problem is code exiting the useEffect block even though I used async for document read to complete. But code is going past useEffect anyway and user details are retrieved after that.
I would like to read the document before control goes out of useEffect.
Please let me know what I am doing wrong.
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
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);
});
}
Upvotes: 0
Views: 338
Reputation: 1281
I tried something like this and it worked. Still not 100% sure what is the difference.
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));
}, []);
Upvotes: 0
Reputation: 111
In order for readDocument
to work with await
it needs to be a promise that gets resolved. https://itnext.io/javascript-promises-and-async-await-as-fast-as-possible-d7c8c8ff0abc - scroll down to section async/await
Something like this (unverified) -
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);
});
});
};
Upvotes: 2