i am retrieving an array of objects containing my firestore storage file information using the function below
export const listFiles = async () => {
const listRef = ref(storage, "/");
const files: any = [];
await listAll(listRef)
.then((res) => {
res.items.forEach((itemRef) => {
getMetadata(itemRef).then((metadata) => {
files.push({
name: metadata.fullPath,
created: metadata.timeCreated,
});
});
});
})
.catch((error) => console.error(error));
return files;
};
in my react front end i call the function the firestore function and set a files state variable equal to the result of the function using code below
const [files, setFiles] = useState<any | any>(null);
...
useEffect(() => {
const fetch = async () => {
const filesList: any = await listFiles();
setFiles(filesList)
};
fetch();
}, []);
i then map over the returned array in the code below (using chakra ui components btw)
<Box textAlign="center">
{files && (
<>
<Text fontSize="3xl">Uploaded Files</Text>
{files.map((file: any) => {
return (
<Box
display="flex"
alignItems="center"
key={file.name}
bg="gray.200"
m={5}
borderRadius="lg"
p="2"
justifyContent="space-between"
>
<Box textAlign="initial">
<Text>{file.name}</Text>
<Text>{file.created}</Text>
</Box>
<Button>
<BsCloudDownload />
</Button>
</Box>
);
})}
</>
)}
</Box>
any ideas why my content appears for a second and then disappears? i've seen others with similar issues in other posts, but have not been able to fix with any solutions i've seen. probably a dumb mistake somewhere, let me know
thanks again
EDIT: i removed try catch from my firestore query.. let me know if this looks right?
export const listTheFiles = async () => {
const listRef = ref(storage);
const files: any = [];
const response = await listAll(listRef);
response.items.forEach(async (itemRef) => {
const metadata = await getMetadata(itemRef);
files.push({ name: metadata.fullPath, created: metadata.timeCreated });
});
console.log(files);
return files;
};
CodePudding user response:
The issue is due to promises inside listFiles
function are not handled correctly, so files
were returned as empty array, even if this array will be populated in future - react will not detect that and will not rerender the component. Also, it is a bad practice to mix async
with .then.catch promises api.
Fixed method:
export const listFiles = async () => {
const listRef = ref(storage, "/");
const listAllResult = await listAll(listRef);
const promises = listAllResult.items.map(async (itemRef) => {
const metadata = await getMetadata(itemRef);
return {
name: metadata.fullPath,
created: metadata.timeCreated
};
});
return Promise.all(promises);
};
Sorry, i cant test it at this moment but if you encounter any issues after that - feel free to comment me and i'll update the answer.
CodePudding user response:
you can try writing the component like this and see if the issue persists :
<Box textAlign="center">
<Text fontSize="3xl">Uploaded Files</Text>
{
files?.map((file) => {
return (
<Box
display="flex"
alignItems="center"
key={file.name}
bg="gray.200"
m={5}
borderRadius="lg"
p="2"
justifyContent="space-between"
>
<Box textAlign="initial">
<Text>{file.name}</Text>
<Text>{file.created}</Text>
</Box>
<Button>
<BsCloudDownload />
</Button>
</Box>
);
})
}
</Box>
it would also be helpful to know if you get any type of error in your console.