What's the best way tu opload a file directly to Supabase storage?

It’s looking like an end of August / early September feature but can’t make any promises because we’re testing a new organization to iterate on existing integrations and the current priorities are supporting the new Xano Metadata API and Airtable’s personal access tokens.

1 Like

Hi,

I’ve tried following this tutorial but receive this error:
image

Here is my JS code:
image

My goal:
Add file on UI → Upload file to supabase storage

Hey, you can do it in a wayyy more simple workflow, check this out


  async function uploadImages(images) {
    const storage = wwLib.wwPlugins.supabaseAuth.publicInstance.storage;
    const promises = [];

    for (let i = 0; i < images.length; i++) {
      const image = images[i];
      const randomName = generateRandomName(); // Implement your random name generation logic
      const filePath = `property_1/bedroom_1/${randomName}.jpg`;

      const promise = storage
        .from('your bucket name here') // Your bucket name goes here
        .upload(filePath, image, {
          cacheControl: '3600',
          upsert: true,
        });

      promises.push(promise);
    }

    // Wait for all upload promises to complete
    await Promise.all(promises);
    if(debug) console.log('Promises fulfilled.');
  }

  // Generate a random name function (you can customize this)
  function generateRandomName() {
    const randomString = Math.random().toString(36).substring(7);
    return randomString;
  }

  // Call the uploadImages function
  uploadImages(images)
    .then(() => {
    if(debug) console.log('Images uploaded.');
    })
    .catch((error) => {
      console.error('Error uploading images:', error);
    });

This is a funtion that lets you upload 1 or infinite amount of images. Like in this demo:

I use it in a formula like this

and then call it like this

I set the value
of images on change of the file upload like this, but you can do it with nocode too, it’s just a part of a bigger js code.

While Roberto’s method is one way of uploading multiple files one by one, from the error I think the main problem is not the method used but the missing element returned from querySelector.

Replace document.querySelector('#my-image input') with wwLib.getFrontDocument().querySelector('#my-image input') and you should be good to go.

1 Like

This will get you all the files within a folder, and it’s subfolders by recursively checking for items in the initial_path to the folder and in the bucket of your choice

async function retrieveItems(initialPath, bucket_name) {
    const folderObject = {
        data: [],
    };

    async function processItem(path, prev_path) {
        const { data, error } = await supabase.storage.from(bucket_name).list((prev_path ? (prev_path + "/") : "") + path, {
            limit: 100,
            offset: 0,
        });

        if (!error && data) {
            // Process the data or do something with it
            const promises = [];

            for (const item of data) {
                if (item.id) folderObject.data.push((prev_path ? (prev_path + "/") : "") + path + "/" + item.name);

                // Check for items without an 'id' and add them to promises
                if (!item.id) {
                    const nestedPath = (prev_path ? (prev_path + "/") : "") + path;
                    promises.push(processItem(item.name, nestedPath)); // Use item.name instead of item.path
                }
            }

            // Wait for all promises to resolve before returning
            await Promise.all(promises);
        } else {
            console.error('Error fetching data:', error);
        }
    }

    // Call the function with the initial path
    await processItem(initialPath);

    const { data, err } = await supabase
        .storage
        .from(bucket_name)
        .createSignedUrls(folderObject.data, 60);

    return data;
}

I received the same error.

double check the id of your element both in the code and the editor.

Which element exactly?

your file input

I see my issue. I have been using the drag and drop uploader and I assume the input type is different. What is the appropriate adjustment here?

If you look into dev tools, you should be aiming for the <input> element.

1 Like

This actually is kinda weird, because it seems like even if you go for the input, it is empty, so probably WeWeb handles those files in a different way?

@mander if you use the code I provided here

async function uploadImages(images, bucket, path) {
    const storage = wwLib.wwPlugins.supabaseAuth.publicInstance.storage;
    const promises = [];

    for (let i = 0; i < images.length; i++) {
      const image = images[i];
      const randomName = generateRandomName(); // Implement your random name generation logic
      const filePath = `${path}/${randomName}.jpg`;

      const promise = storage
        .from(bucket) // Your bucket name goes here
        .upload(filePath, image, {
          cacheControl: '3600',
          upsert: true,
        });

      promises.push(promise);
    }

    // Wait for all upload promises to complete
    await Promise.all(promises);
    console.log('Promises fulfilled.');
  }

  // Generate a random name function (you can customize this)
  function generateRandomName() {
    const randomString = Math.random().toString(36).substring(7);
    return randomString;
  }

  // Call the uploadImages function
  uploadImages(variables[/* Input File Drop - value */ 'cdd23a87-baa8-4fe8-9782-69efde43c67b-value'], 'bucket_name', 'your_path/your_folder') // You just input your [ Input File Drop - value ] here
    .then(() => {
    console.log('Images uploaded.');
    })
    .catch((error) => {
      console.error('Error uploading images:', error);
    });
    

You can use the variable from the upload directly. Like this:

Seems to work,

No need to overcomplicate it by using queries and such.

2 Likes