Vue.jsでFirebase Storageに画像をアップロード・取得

前書き

ポートフォーリオ作成で、自分の開発した作品を自分で投稿できるようにしようということで、
Firebaseを活用してみました。今回は画像を一旦、Storageに格納する処理を書いていきます。

これまで

Firebaseに関する設定をこちらで記載しました。
ここでの設定をしておかないとStorageにアクセスする際、404や403が吐かれます。

melheaven.hatenadiary.jp

実装

./plugins/auth.js(画像をStorageに格納)

こちらではfirebaseとの接続に関する処理を書いています。
Databaseとの送受信処理やStorageへの格納処理をまとめて関数化して置くことで、
vueファイルから関数として呼び出すだけで活用できます。

imageURLでは、Firebase Storage上に保存するパスを指定します。
今回は投稿別に画像サムネイルを保存したいので、投稿名をそのままIDとしました。
file="画像ファイル"、serviceID="保存したいファイル名"を引数としたuploadメソッドの完成です。

export function upload (file, serviceID) {
    const imageURL = `tmp/${serviceID}`
    return  firebase.storage().ref().child(imageURL).put(file,
      function(error) {
        if (error) {
          // The write failed...
          alert('画像のアップロードに失敗しました');
          console.log(error);
        } else {
          console.log("Image file saved successfully!")
        }
      })
}

./plugins/auth.js(画像をStorageから取得)

こちらでは画像をStorageから取得する際に、
getDownloadURL()メソッドを活用し、これによりファイルをダウンロードし、
保存先のURLをStorage参照で取得できます。
title="取得したいファイル名"を引数としたdownloadメソッドの完成です。

export function download (title) {
  const imageURL = `tmp/${title}`
  return firebase.storage().ref().child(imageURL).getDownloadURL(
    function(error) {
      if (!error) {
        alert('画像のダウンロードに失敗しました');
        console.log(error)
      } else {
        console.log("Download URL successfully!")
      }
    }
  )
}

Vue file(画像をStorageに格納)

画像送信ページVueファイルでは、
画像を選択した時に、選択中の画像を表示できるようにします。

f:id:electric-city:20201129171651p:plain

<img v-if="uploadImageUrl" :src="this.uploadImageUrl" />
<v-file-input v-model="input_image"
                    accept="image/*"
                    show-size
                    label="画像ファイルをアップロードしてください"
                    prepend-icon="mdi-image"
                    @change="onImagePicked"></v-file-input>

次に送信ボタンを押すと、先ほど作成したuploadメソッドを呼び出します。
onImagePickedメソッドで選択した画像を一旦ブラウザ上に表示する機能の完成です。

import { post, upload } from '@/plugins/auth'

export default {
    data() {
        return {
             uploadImageUrl: "",
        }
      },
 methods: {
  submit() {
           upload(this.input_image, this.formdata.title).then(() => {
                        // 画像をアップロードしました
                })
        },
       onImagePicked(file) {
            if (file !== undefined && file !== null) {
                if (file.name.lastIndexOf('.') <= 0) {
                return
                }
                const fr = new FileReader()
                fr.readAsDataURL(file)
                fr.addEventListener('load', () => {
                this.uploadImageUrl = fr.result
                })
            } else {
                this.uploadImageUrl = ''
            }
        }
    }

Vue file(画像をStorageから取得)

こちらでは先ほど作成したdownloadメソッドを活用します。

download(docdata.title)
                    .then((imageurl) => {
                        // Vueに埋め込む場合は<v-img :src="~URL~">
                        // 画像をBlob化したり
                        // 配列に格納する
                        docdata['imageurl'] = imageurl;
                        get_list.push(docdata);
                    }); })

結果

f:id:electric-city:20201129183726p:plain