minio / minio-js

MinIO Client SDK for Javascript
https://docs.min.io/docs/javascript-client-quickstart-guide.html
Apache License 2.0
920 stars 271 forks source link

Uploading File from Next.js #1275

Closed JosephVoid closed 4 months ago

JosephVoid commented 4 months ago

Hey,

I'm currently trying to upload file file from my Next.js app to min-io. Here is the function that handles that: file is a base64 string representation of the file, and name is the name

export async function fileUpload(file: string, name: string) {
  let blob = new Blob([file]);

  minioClient.putObject(
    "images",
    name,
    blob.stream(), // here
    function (err, objInfo) {
      if (err) {
        return console.log(err); // err should be null
      }
      console.log("Success", objInfo);
    }
  );
}

I converted the base64 string into a blob, then turned it to a stream. the blob.stream() returns a ReadableStream<Uint8Array> but minio still tells me it's incompatible?

What is going on? If i am completely missing the plot, can you even upload directly from the front-end? Thanks

prakashsvmx commented 4 months ago

Web Streams and NodeJs Streams are not compatible. you can try one of the following

const fileReader = new FileReader();
      fileReader.onload = async function(evt) {
        if (evt.target.readyState === FileReader.DONE) {
          // Get the unsigned 8 bit int8Array (ie Uint8Array) of the 600 bytes (this looks like '[119,80,78,71...]'):
          const uint = new Uint8Array(evt.target.result);

         //pass it to MinIO-JS
          await mc.putObject(bucketName, `${targetPrefix ? targetPrefix : ""}${fileName}`, Buffer.from(uint), {
            "Content-Type": file.type,
            "X-Amz-Meta-App": "SPH-REACT-JS"
          });
        }
      };
      fileReader.onerror = function() {
        fileReader.abort();
      };
      fileReader.readAsArrayBuffer(file);

or use a library like:

let fileReaderStream = require('filereader-stream')

 let readStream = fileReaderStream(file )

      await mc.putObject(bucketName, `${targetPrefix ? targetPrefix : ""}${fileName}`, readStream, {
        "Content-Type": file.type,
        "X-Amz-Meta-App": "SPH-REACT-JS"
      });
JosephVoid commented 4 months ago

Thanks @prakashsvmx,

But I got it working like this for now:

export async function fileUpload(
  file: string | null,
  name: string | null
): Promise<string | null> {
  /* file is base64 string of the binary */

  if (file && name) {
    let blob = Base64ToBlob(file);
    const buffer = Buffer.from(await blob.arrayBuffer());

    const bucket = "test-bucket";

    const exists = await minioClient.bucketExists(bucket);
    if (exists) {
      console.log("Bucket " + bucket + " exists.");
    } else {
      await minioClient.makeBucket(bucket, "us-east-1");
      console.log("Bucket " + bucket + ' created in "us-east-1".');
    }

    minioClient.putObject(
      bucket,
      sanitizeName(name),
      buffer,
      function (err, objInfo) {
        if (err) {
          return console.log(err); // err should be null
        }
      }
    );
    let URL = `${process.env.NEXT_PUBLIC_MINIO_PROT}://${
      process.env.NEXT_PUBLIC_MINIO_URL
    }:${process.env.NEXT_PUBLIC_MINIO_PORT}/${bucket}/${sanitizeName(name)}`;
    return URL;
  }

  return null;
}