node.jsexpressnpmnode-modulesbackblaze

Upload multiple files to BackBlaze according to the original filename


I'm trying to upload images to BackBlaze using backblaze-b2 npm module from a folder that has multiple images and for each image successfully uploading I push the fileId to an array all the files in the folder is named from 0001.jpg to how many files there are in this was if there are 12 images in the folder the last image will be named 0012.jpg but after all images are uploaded and the ids are pushed into the array it'll be like 2nd image's id will place placed on 5th or 6th in the array the last image will be placed at the first

Here is the code I'm using

export const uploadToBackBlaze = async (req, res, next) => {
  // Defining backblaze masterkey and application key

  const b2 = new B2({
    applicationKeyId: process.env.BACKBLAZE_MASTER_APPLICATION_KEY_ID,
    applicationKey: process.env.BACKBLAZE_MASTER_APPLICATION_ID,
  });

  const __dirname = path.resolve(); // Defining directory
  let tempDir = path.join(__dirname, "chapterTemp"); // the temp directory

  const imageIds = []; // Empty array where the file IDs will be pushed

  try {
    await b2.authorize().then(async () => {
      const bucketId = process.env.BACKBLAZE_BUCKET_ID;

      fs.readdir(tempDir, async function (err, files) {
        if (err) {
          console.error(err);
          res.sendStatus(500).json({ message: err.message });
          return;
        }

        // Unique id

        let uid = uuidv4();

        // Reading file from temp Dir and upload to backblaze

        const uploadPromises = files.map(async (file) => {
          const fileData = fs.readFileSync(path.join(tempDir, file));
          const uploadFileName = path.join(uid, file); // changing file name to uniques
          const uploadUrl = await b2.getUploadUrl(bucketId); // Getting upload URL and auth token
          const response = await b2.uploadFile({
            uploadUrl: uploadUrl.data.uploadUrl,
            uploadAuthToken: uploadUrl.data.authorizationToken,
            filename: uploadFileName,
            data: fileData,
            mime: "image/png" || "image/jpg" || "image/jpeg" || "image/webp", // replace with the appropriate MIME type for your files
          });

          imageIds.push(response.data.fileId);
        });

        await Promise.all(uploadPromises);

        req.imageIds = imageIds;
        next();
      });
    });
  } catch (error) {
    return res.status(500).json({ message: error.message });
  }
};

I want the array to have the file ids in order like 1.jpg's file id should one on the imageIds[0] position and 2.jpg should be on the imageIds[1] position and so on!


Solution

  • Doing this fixed the issue and It's been working fine after I tried it multiple times

    import fs from "fs";
    import B2 from "backblaze-b2";
    import path from "path";
    import dotenv from "dotenv";
    import { v4 as uuidv4 } from "uuid";
    
    dotenv.config();
    
    export const uploadToBackBlaze = async (req, res, next) => {
      // Defining backblaze masterkey and application key
    
      const b2 = new B2({
        applicationKeyId: process.env.BACKBLAZE_MASTER_APPLICATION_KEY_ID,
        applicationKey: process.env.BACKBLAZE_MASTER_APPLICATION_ID,
      });
    
      const __dirname = path.resolve(); // Defining directory
      let tempDir = path.join(__dirname, "processed"); // the temp directory
    
      try {
        await b2.authorize().then(async () => {
          const bucketId = process.env.BACKBLAZE_BUCKET_ID;
    
          fs.readdir(tempDir, async function (err, files) {
            if (err) {
              console.error(err);
              res.sendStatus(500).json({ message: err.message });
              return;
            }
    
            // Unique id
    
            let uid = uuidv4();
    
            // Reading file from temp Dir and upload to backblaze
    
            const uploadPromises = files.map(async (file) => {
              const fileData = fs.readFileSync(path.join(tempDir, file));
              const uploadFileName = path.join(uid, file); // changing file name to uniques
              const uploadUrl = await b2.getUploadUrl(bucketId); // Getting upload URL and auth token
              const response = await b2.uploadFile({
                uploadUrl: uploadUrl.data.uploadUrl,
                uploadAuthToken: uploadUrl.data.authorizationToken,
                filename: uploadFileName,
                data: fileData,
                mime: "image/png" || "image/jpg" || "image/jpeg" || "image/webp", // replace with the appropriate MIME type for your files
              });
    
              return response.data.fileId;
            });
    
            req.imageIds = await Promise.all(uploadPromises);
            fs.rmdirSync(tempDir, { recursive: true }); // Removing Files From Temp Dir
            next();
          });
        });
      } catch (error) {
        fs.rmdirSync(tempDir, { recursive: true }); // Removing Files From Temp Dir
        return res.status(500).json({ message: error.message });
      }
    };

    Instead of pushing the Image Ids into an array if I just send the Promise.all(uploadPromises) as req.imageIds the image Ids are resolved into an array in the some order of their original File Name