Как создать папку в Firebase Storage с помощью Admin API - PullRequest
0 голосов
/ 28 февраля 2019

Цель: загрузить файл в папку в Firebase Storage

Например,

default_bucket/folder1/file1
default_bucket/folder1/file2
default_bucket/folder2/file3

Использование Firebase client-сторона Я могу загрузить файл в папку в Firebase Storage следующим образом:

    const storageRef = firebase.storage().ref();
    const fileRef = storageRef.child(`${folder}/${filename}`);
    const metadata = {
      contentType: file.type,
      customMetadata: { }
    };
    return fileRef.put(file, metadata);

Если папка не существует, она создается.

ОднакоМне не удалось сделать то же самое на стороне сервера, используя Admin SDK.

Приведенный ниже код загружает файл в корзину по умолчанию.

Но я хочу загрузитьфайл в именованную папку в контейнере по умолчанию.

Клиентская сторона делает запрос POST в GCF, отправляя файл и имя папки.

Busboy используется для добавления имени папки ифайл и передать их в функцию загрузки;который загружает файл, а затем возвращает для него ссылку для загрузки.

index.js

const task = require('./tasks/upload-file-to-storage');

app.post('/upload', (req, res, next) => {
  try {
    let uploadedFilename;
    let folder;

    if (req.method === 'OPTIONS') {
      optionsHelper.doOptions(res);
    } else if (req.method === 'POST') {
      res.set('Access-Control-Allow-Origin', '*');

      const busboy = new Busboy({ headers: req.headers });
      const uploads = [];

      busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
        uploadedFilename = `${folder}^${filename}`;

        const filepath = path.join(os.tmpdir(), uploadedFilename);
        uploads.push({ file: filepath, filename: filename, folder: folder });
        file.pipe(fs.createWriteStream(filepath));
      });

      busboy.on('field', (fieldname, val) => {
        if (fieldname === 'folder') {
          folder = val;
        } 
      });

      busboy.on('finish', () => {
        if (uploads.length === 0) {
          res.end('no files found');
        }
        for (let i = 0; i < uploads.length; i++) {
          const upload = uploads[i];
          const file = upload.file;

          task.uploadFile(helpers.fbAdmin, upload.folder, upload.file, uploadedFilename).then(downloadLink => {
            res.write(`${downloadLink}\n`);
            fs.unlinkSync(file);
            res.end();
          });
        }
      });
      busboy.end(req.rawBody);
    } else {
      // Client error - only support POST
      res.status(405).end();
    }
  } catch (e) {
    console.error(e);
    res.sendStatus(500);
  }
});

const api = functions.https.onRequest(app);

module.exports = {
  api
;

upload-file-to-storage.js

exports.uploadFile = (fbAdmin, folder, filepath, filename) => {
  // get the bucket to upload to
  const bucket = fbAdmin.storage().bucket(); //`venture-spec-sheet.appspot.com/${folder}`

const uuid = uuid();
  // Uploads a local file to the bucket
  return bucket
    .upload(filepath, {
      gzip: true,
      metadata: {
        //destination: `/${folder}/${filename}`,
        cacheControl: 'public, max-age=31536000',
        firebaseStorageDownloadTokens: uuid
      }
    })
    .then(() => {
      const d = new Date();
      const expires = d.setFullYear(d.getFullYear() + 50);

      // get file from the bucket
      const myFile = fbAdmin
        .storage()
        .bucket()
        .file(filename);

      // generate a download link and return it
      return myFile.getSignedUrl({ action: 'read', expires: expires }).then(urls => {
        const signedUrl = urls[0];
        return signedUrl;
      });
    });
};

Я пробовал несколько вещей

Установка имени корзины по умолчанию и папки.Это привело к ошибке сервера.

const bucket = fbAdmin.storage().bucket(`${defaultName}/${folder}`); 

Установка имени корзины в папку.Это привело к ошибке сервера.

const bucket = fbAdmin.storage().bucket(folder); 

И я также попытался использовать свойство назначения uploadOptions .Но это все равно помещает файл в корзину по умолчанию.

    .upload(filepath, {
      gzip: true,
      metadata: {
        destination: `${folder}/${filename}`, // and /${folder}/${filename}
      }
    })

Можно ли загрузить в папку, используя Admin SDK?

Например, я хочу загрузитьтак что файл помещается в именованную «папку».

Т.е. чтобы я мог ссылаться на файл по пути: bucket / folder / file.jpg

В приведенном ниже примере каждый«папка» именуется ключом firebase.

enter image description here

1 Ответ

0 голосов
/ 04 марта 2019

Нашел проблему.Я тупо объявил опцию назначения в неправильном месте.

Вместо объекта метаданных:

 return bucket
    .upload(filepath, {
      gzip: true,
      metadata: {
        destination: `${folder}/${filename}`,
        cacheControl: 'public, max-age=31536000',
        firebaseStorageDownloadTokens: uuid
      }
    })

Это должно было быть в объекте опций:

 return bucket
    .upload(filepath, {
      gzip: true,
      destination: `${folder}/${filename}`,
      metadata: {   
        cacheControl: 'public, max-age=31536000',
        firebaseStorageDownloadTokens: uuid
      }
    })

После внесения этого изменения файл теперь загружается в именованную "папку".

...