This page looks best with JavaScript enabled

Uploading Files in Vue Firestore App

 ·   ·  ☕ 4 min read

Firestore is a super easy way to configure your backend. Firestore provides a range of services anywhere from a database, user authentication, to using machine learning for many use-cases.

One of the many things you do in a typical app is to enable users to store files. While some find it easier to store files in database (huh?), the most popular option is to store files and reference them in the database record.

Firestore provides easy access to a service known as Firebase Storage to store files. Let’s see how.

Create Vue View

We get started with a simple Vue app (which is using Vuetify, but that does not matter)..

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<template>
  <v-container>
    <v-row>
      <v-col cols="12" class="mt-12 pt-md-6" align="center">
        <span class="title font-weight-black">Image Handler</span>
      </v-col>
      <v-col cols="12" class="mt-12" align="center">
        <v-file-input
          v-model="myFile"
          outlined
          :rules="[rules.maxsize]"
          accept="image/png, image/jpeg"
          placeholder="Click to upload file"
          @change="fileInput"
          :disabled="processing"
        >
          <template v-slot:append-outer>
            <v-progress-circular
              v-if="processing"
              color="grey"
              indeterminate
              small
            />
          </template>
        </v-file-input>
      </v-col>
      <v-col cols="12" align="center">
        <v-img :src="fileUrl" contain v-if="fileUrl" max-height="500"></v-img>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
  import { mapState, mapMutations } from "vuex";
  import { FirebaseFunctions, FirebaseStorage } from "@/services/firebase.js";

  export default {
    data() {
      return {
        myFile: null,
        processing: false,
        fileUrl: null,
      };
    },
  };
</script>

Add a Service to invoke Firebase

Install Firebase in your vue app.

1
npm i firebase

Add a service that can be consumed by any Vue components to upload files - src/services/firebase.js.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import firebase from "firebase/app";
import "firebase/storage";
// get config from Firebase console
const firebaseConfig = {
  apiKey: "the_api_key",
  authDomain: "myapp.firebaseapp.com",
  databaseURL: "https://myapp.firebaseio.com",
  projectId: "myapp",
  storageBucket: "myapp.appspot.com",
  messagingSenderId: "12345",
  appId: "1:123512:web:1abcd23",
  measurementId: "G-123COOL",
};

firebase.apps && !firebase.apps.length
  ? firebase.initializeApp(firebaseConfig)
  : "";

export const FirebaseStorage = firebase.storage();
export default firebase;

We add the above code as a service instead of using them locally in components (or views) since we may need the same code in multiple places.

A few key points to note -

  • Get configuration from your Firebase console. This forms the entirety of firebaseConfig object
  • We export FirebaseStorage (alongside firebase) and this a ready-to-use service to access the Firebase storage

In the next section you will see how we use this service.

Add Method to Upload File

Finally, add the methods to handle image uploads in the view.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<script>
  import { FirebaseStorage } from "@/services/firebase.js";

  export default {
    data() {
      return {
        myFile: null,
        processing: false,
        fileURL: null,
      };
    },
    methods: {
      async fileInput(file) {
        try {
          if (file && file.name) {
            this.processing = true;

            const fr = new FileReader();
            fr.readAsDataURL(file);
            fr.addEventListener("load", () => {
              // this is to load image on the UI
              // .. not related to file upload :)
              this.fileURL = fr.result;
            });
            const imgData = new FormData();
            imgData.append("image", this.myFile);
            const filePath = `mypath/${Date.now()}-${file.name}`;
            const metadata = { contentType: this.myFile.type };

            await FirebaseStorage.ref()
              .child(filePath)
              .put(this.myFile, metadata);
            console.log("filePath: ", filePath);
          }
        } catch (e) {
          console.error(e);
        } finally {
          this.processing = false;
        }
      },
    },
  };
</script>

We are doing a few simple things here -

  • We read the file using const fr = new FileReader(); and display the file on the UI. This is just a “nice to have” feature to provide feedback to user when she selects the file
  • The selected file gets appended to form data - const imgData = new FormData()
  • Upload the file to the path const filePath = ``mypath/${Date.now()}-${file.name}``; on our Firebase storage using FirebaseStorage.ref()

That is it! You can now upload any file to Firestore (provided your security rules allow you to upload files).

Stay in touch!
Share on

Prashanth Krishnamurthy
WRITTEN BY
Prashanth Krishnamurthy
Technologist | Creator of Things