/ Firebase

Upload Files to Firebase Storage with JavaScript


Firebase is has proved itself to be very robust Realitime Database solution; and with new API, it provides Storage of files as well.

This reduces the Server-side headache of handling files to bare minimum.

We will be going through a simple application to upload images to the Firebase Hosting along with some basic CRUD operations and authentication with Firebase. As we have already covered both topics on following location, we will be concentrating more on the file upload.

Steps:

Basic process for file upload is

  1. create firebase storage reference

    const ref = firebase.storage().ref();
    
  2. Now get the file to be uploaded from the input[type="file"]

    const file = $('#photo').get(0).files[0];
    

    OR

    const file = document.querySelector('#photo').files[0];
    
  3. Now prepare the filename and metadata for the uploaded file
    3.1. Filename

    we can easily get the name of file being uploaded by the name property of the file being uploaded as follows

    const name = file.name;
    

    but it is not a good idea to keep the file name as only identifier, we will use timestamp as well in the beginning of the file name as following=

    const name = (+new Date()) + '-' + file.name;
    

    3.2. Metadata

    Metadata needs the object which should contain contentType key. contentType is the file type which can be taken from the file.type

    const metadata = { contentType: file.type };
    
  4. Create the file upload task, this file upload task will be handled by the .put() method on storage child. This task is a Promise and hence we can easily operate on this task later

    const task = ref.child(name).put(file, metadata);
    

    The task also supports following methods to handle file upload:

    // Pause the upload
    task.pause();
    
    // Resume the upload
    task.resume();
    
    // Cancel the upload
    task.cancel();
    
  5. Use the response of file upload

    task.then((snapshot) => {
        console.log(snapshot.downloadURL);
    });
    

As in above steps, the file upload is complete, though there are few things to notice:

  • You can save the downloadURL of the uploaded file like above; or you can save the fire ref and use it later to get the download URL like as follows
    const image = ref.child('kingsman.jpg');
    const urlPromise = image.getDownloadURL();
    
    urlPromise.then(url => {
        document.querySelector('#someImageTagID').src = url;
    }
    
  • There can be many cases of error which you will need to handle in the upload task by the .catch() method of promise like as follows:
    task
        .then((snapshot) => {
          document.querySelector('#someImageTagID').src = snapshot.downloadURL;
        })
        .catch((error) => {
          // A full list of error codes is available at
          // https://firebase.google.com/docs/storage/web/handle-errors
          switch (error.code) {
            case 'storage/unauthorized':
              // User doesn't have permission to access the object
              break;
            case 'storage/canceled':
              // User canceled the upload
              break;
            ...
            case 'storage/unknown':
              // Unknown error occurred, inspect error.serverResponse
              break;
          }
        })
    
  • All properties of the returned snapshot are:
    Property Type Writable
    bucket string NO
    generation string NO
    metageneration string NO
    fullPath string NO
    name string NO
    size number NO
    timeCreated string NO
    updated string NO
    md5Hash string YES on upload, NO on updateMetadata
    cacheControl string YES
    contentDisposition string YES
    contentEncoding string YES
    contentLanguage string YES
    contentType string YES
    downloadURLs Array NO
    customMetadata Object YES

Final Code:

const ref = firebase.storage().ref();
const file = document.querySelector('#photo').files[0]
const name = (+new Date()) + '-' + file.name;
const metadata = {
  contentType: file.type
};
const task = ref.child(name).put(file, metadata);
task.then((snapshot) => {
  const url = snapshot.downloadURL;
  console.log(url);
  document.querySelector('#someImageTagID').src = url;
}).catch((error) => {
  console.error(error);
});

Demo:

The movie DB demo which we created in earlier posts is now equipped with the moviePoster upload as well.

Demo Download