In my next.js app I am trying to upload image from form. But I keep getting an error:
[Error] Unhandled Promise Rejection: TypeError: Load failed
And the file doesn't upload to supabase.
I checked the image variable via console, it is a File object. Here is how I do it, I followed the tutorial in documentation:
import * as Form from "@radix-ui/react-form";
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(
"url",
"api-key",
);
export default function Warehouses() {
async function uploadImage(e) {
const image = e.files[0];
const { data, error } = await supabase.storage
.from("images")
.upload("/", image);
if (data) {
console.log(data);
} else {
console.log(error);
}
}
const onSubmit = (event) => {
uploadImage(event.target.images);
};
return (
<div>
<Form.Root className="FormRoot" onSubmit={onSubmit}>
<Form.Field className="FormField" name="images">
<div
style={{
display: "flex",
alignItems: "baseline",
justifyContent: "space-between",
}}
>
<Form.Label className="FormLabel">
Upload Images
</Form.Label>
</div>
<Form.Control asChild>
<input
type="file"
id="images"
name="images"
multiple
/>
</Form.Control>
</Form.Field>
<Form.Submit asChild>
<Button>Create</Button>
</Form.Submit>
</Form.Root>
</div>
);
}
I will appreciate any help!
UPDATE
I get this error in Safari browser also:
[Error] Fetch API cannot load https://my-url/storage/v1/object/images/2 due to access control checks.
Here is what I get from console.log(image) inside uploadImage():
I also tried to check the connection to supabase with this code:
export async function getServerSideProps() {
const buckets = await supabase.storage.listBuckets();
console.log(buckets);
return {
props: {
bucketList: buckets,
},
};
}
But I get this in the console: ``` { data: [], error: null } ``
Below are the policies to my supabase bucket "images":
Here is the first (select) policy edit window:
Here is how the policies were added to my bucket:
You are not uploading the file in a way that passes the insert policy you have in place.
The issue is that you have the storage.foldername(name)[1] = 'public'
, but you are not uploading the image in a public
folder. For this poilcy to pass, you need to upload the image into /public
path instead of /
. I assume what you meant here is that you are uploading an image to a public bucket, but that is different from uploading to a public path. I think you can remove the storage.foldername(name)[1] = 'public'
statement.
Also, there are other things you can remove as well. First, we recently added a feature to restrict the meme types of the object being uploaded to a bucket. You can set it like this to only accept jpg.
About the role, the correct way to specify which role you want the policy to be applied to is to select the target roles
from the policy editor. You can set this to anon
to target anon users.
With all of that, you should be left with the following simple policy for what you want to do.
Note that having users sign in to your app is not essential, but might be something to consider before you start promoting your app, because otherwise anyone can upload images to your bucket without any restrictions.