volpe’s diary

フリーランスじゃなくなったプログラマ volpe が日々便利だなぁと感じたことを中心に綴るブログです

Nuxt.js + Firebase で画像ファイルアップロードする

Firestorage に画像ファイルをアップロードしたくなったのでやってみる。

やってることは一般的なファイルアップロードの流れと変わらないが、Firestorage にアップロードする処理は store の action として実装している。

まずは view に form を設置する。 @change イベントハンドラを設定する。

input(type="file", :multiple="false", accept="image/*", @change="detectFiles($event)")

次に methods にファイル選択時のイベントハンドラを定義する。 アップロードするファイル名は他と被らないように uuid ライブラリを使って動的に生成している。 ファイル名とファイル本体を取得したら store の uploadImage へ渡す。

import uuid from 'uuid'
           :
  methods: {
    detectFiles(e) {
      // アップロード対象は1件のみとする
      const file = (e.target.files || e.dataTransfer.files)[0]
      if (file) {
        const fileName = uuid()

        this.$store
          .dispatch('personas/uploadImage', {
            name: fileName,
            file: file
          })
          .then(url => {
            // アップロード完了処理 (ローカルメンバに保存したり)
            this.fileName = fileName
            this.imageUrl = url
          })
      }
    }
  }

store では実際に Firestorage にアップロードする処理を書く。 ここではエラー処理や進捗情報は無視して正常系のみ実装している。 ファイルを上書きしたい場合は、ref() で指定するファイル名に既に存在するファイル名を指定するといい。 取得した url を DB に保持しておけば任意のタイミングで画像を表示できる。

store/persona.js

import firebase from '@/plugins/firebase'
const firestorage = firebase.storage()

export const actions = {
              :
 uploadImage: (context, payload) => {
    return new Promise((resolve, reject) => {
      // firestorage にファイルをアップロード
      const uploadTask = firestorage
        .ref('images/' + payload.name)
        .put(payload.file)
        .then(snapshot => {
           // アップロード完了処理。URLを取得し、呼び出し元へ返す。
           snapshot.ref.getDownloadURL().then(url => {
             resolve(url)
           })
         })
      )
    })
  }
}

これで画像ファイルをアップロードしまくれるぞ!