1

I am currently learning Firebase.

I have a requirement that from HTML I can transfer the file(.zip) successfully to firebase storage bucket.

My question, is it possible to unzip the file after uploading complete at firebase storage server.

I can do that using PHP, I just wonder if same is possible using Firebase without any server code.

raju
  • 6,448
  • 24
  • 80
  • 163

3 Answers3

2

I believe you can achieve it by leveraging cloud functions. You can write storage triggers for paths and once a zip file is uploaded, it triggers the cloud function which unzips the file to where you want it. To save space you can also delete the zip file after unzipping it.

danialmoghaddam
  • 343
  • 1
  • 6
  • 21
-1

No, the file you upload from the client gets stored as exactly the same file in your storage bucket. There is not currently a way to automatically change that stored file after it's been uploaded.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
-1

There is a way to perform it with FirebaseFunctions. We can modify the code in Aeyrium's answer to this Stack Overflow question to suite our requirements, as follows:

const functions = require('firebase-functions');
const admin = require("firebase-admin");
const path = require('path');
const fs = require('fs');
const os = require('os');
const unzip = require('unzipper')
var serviceAccount = require("./serviceAccountKey.json");

const firebaseConfig = {
  apiKey: "*",
  authDomain: "*",
  databaseURL: "*.firebaseio.com",
  projectId: "*",
  storageBucket: "p*.appspot.com",
  messagingSenderId: "*",
  appId: "*",
  measurementId: "*",
  credential: admin.credential.cert(serviceAccount)
};


admin.initializeApp(firebaseConfig);

const storage = admin.storage();


const runtimeOpts = {
  timeoutSeconds: 540,
  memory: '256MB'
}

exports.unzip = functions.runWith(runtimeOpts).storage.object().onFinalize((object) => {

    return new Promise((resolve, reject) => {
        //console.log("objct is:",object)

        if (object.contentType !== 'application/x-zip') {
          reject();
        } else {
          //const bucket = admin.storage.bucket(object.bucket)
      const bucket = admin.storage().bucket()
          const remoteFile = bucket.file(object.name)
          const remoteDir = object.name.replace('.zip', '')

          console.log(`Downloading ${remoteFile}`)

          remoteFile.createReadStream()
            .on('error', err => {
              console.error(err)
              reject(err);
            })
            .on('response', response => {
              // Server connected and responded with the specified status and headers.
              //console.log(response)
            })
            .on('end', () => {
              // The file is fully downloaded.
              console.log("Finished downloading.")
              resolve();
            })
            .pipe(unzip.Parse())
            .on('entry', entry => {
              const file = bucket.file(`${remoteDir}/${entry.path}`)

              entry.pipe(file.createWriteStream())
              .on('error', err => {
                console.log(err)
                reject(err);
              })
              .on('finish', () => {
                console.log(`Finsihed extracting ${remoteDir}/${entry.path}`)
              });

              //entry.autodrain();

            });
        }
    })

});

Also, there is a short tutorial about that here in TypeScript.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Arkady
  • 624
  • 1
  • 8
  • 17