• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Protected User Uploadable Files With Firebase Storage

Firebase · August 11, 2020

Recently, while I was building an application on Firebase and implementing Firebase Storage, I realised that I have to always consult old Firebase projects I have built or scour the web for blogs and documentation that explain not only how to do uploads to Firebase Storage but also write rules to protect them.

My use-case is as follows:

  • Users can create listings
  • A listing can have one or more images
  • An image is uploaded to Firebase Storage in the form of listing-images/userId/filename.extension
  • I only want to allow users to write to this folder if they are that user currently logged in. This folder becomes a bucket for all of the users listing images.

Uploading Files

const storage = firebase.storage().ref(`listing-images/${this.auth.currentUser.uid}/${image.name}`);
const upload = storage.put(image);

upload.on('state_changed',
    // Uploading... 
    (snapshot) => {
        this.frontImageUploading = true;
    }, 
    // Error
    () => {
        this.frontImageUploading = false;
    }, 
    // Complete
    () => {
        this.frontImageUploading = false;
    }
);

Uploading files with Firebase’ Javascript SDK could not be any easier. You create a reference to where you want to store a file and then you call the put method providing a file to upload.

We then listen to the state_changed event which can take three callback functions. The first is called as the file is uploaded, the second is the error callback and the third is called when a file has been uploaded.

Firebase Storage Rules

My storage.rules file ended up looking like this. Your use-case might differ, but the premise is the same.

I want to allow all reads as these images are public, so I create a rule called allow read and provide if true as the value.

For image writes, I first check if the currently logged in user matches the userId provided in the image path. I then check if the size of the image is less than 5mb and if its content type is an image.

rules_version = '2';

service firebase.storage {
  match /b/{bucket}/o {
    match /listing-images/{userId}/{allPaths=**} {
      allow read: if true;
      allow write: if request.auth.uid == userId && request.resource.size < 5 * 1024 * 2014 && request.resource.contentType.matches('image/.*');
    }
  }
}

This allows users to only be able to upload to their specific folder inside of listing-images. Anyone can read it, but only the logged-in user can upload here. It’s simple and it works.

Accessing The Uploaded File

Once the file has successfully uploaded, you most likely want to access some information about it like where it uploaded and so on. We can use the reference we created to get that information.

const storage = firebase.storage().ref(`listing-images/${this.auth.currentUser.uid}/${image.name}`);
const upload = storage.put(image);

upload.on('state_changed',
    // Uploading... 
    (snapshot) => {
        this.frontImageUploading = true;
    }, 
    // Error
    () => {
        this.frontImageUploading = false;
    }, 
    // Complete
    async () => {
        this.frontImageUploading = false;

        const meta = await storage.getMetadata();
    }
);

We made the success callback async and then we awaited the getMetadata method which is called on the ref itself. This gives us information like which bucket the file is in, the fullPath, it’s md5Hash, size and other useful values.

If you want to generate an image URL string to the file which can be used in the browser, you can call getDownloadURL(); like so.

const url = await storage.getDownloadURL();

Dwayne

Leave a Reply Cancel reply

0 Comments
Inline Feedbacks
View all comments

Primary Sidebar

Popular

  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • How To Paginate An Array In Javascript
  • Handling Errors with the Fetch API
  • ChatGPT Stopping Part Way Through a Response? Here Is How You Fix It
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How to Use Neural DSP Archetype Plugins With the Quad Cortex
  • How To Mock uuid In Jest

Recent Comments

  • CJ on Microsoft Modern Wireless Headset Review
  • Dwayne on Microsoft Modern Wireless Headset Review
  • CJ on Microsoft Modern Wireless Headset Review
  • john on Microsoft Modern Wireless Headset Review
  • Dwayne on Why You Should Be Using globalThis Instead of Window In Your Javascript Code

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz