Nuxt.js と Firebase Storage でファイルをアップロードする方法

📅 August 30, 2019

⏱️2 min read

Nuxt.js で開発しているときに Firebase の storage にファイルを保存したときの備忘録。 ここでは、FileInput.vueというコンポーネントを作ったこととします。

大まかな概要としては、以下のとおりです。

  • input 要素を設置
  • @changeイベントにより、fileChanged()関数を実行
  • store 内部に定義したuploadFile()関数によってアップロード

Html の input 要素を設置する

type属性に file、@changefileChanged()関数を実行するようにします。

<!-- FileInput.vue -->
<input id="file-input" type="file" @change="fileChanged($event)" />

fileChanged()関数を定義

input 要素からファイルが入力されると、この関数が呼ばれます。 uuid ライブラリを使ってファイル名を生成し、payloadオブジェクトとして database/uploadFileをディスパッチします。

import * as uuidv4 from 'uuid/v4'
// FileInput.vue
async fileChanged(e) {
  const file = (e.target.files || e.dataTransfer.files)[0]
  if (file) {
    const fileName = uuidv4()
    try {
      const uploadTask = await this.$store.dispatch('database/uploadFile', {
        fileName,
        file
      })
    } catch (error) {
      console.error('file upload', error)
    }
  }
}

uploadFile()関数をストア内部に定義

指定したrefの値に応じて、ファイルをストレージに保存します。 ここでは、サンプルのためにpublic/としていますが、public/${hoge}/${fuga}のように 動的に ref 指定することが多いですかね。

// database/uploadFile
const storage = firebase.storage()
const auth = firebase.auth()

async uploadFile({ commit }, payload) {
  try {
    if (!payload) throw new Error('payload is required')

    const currentUser = await auth.currentUser
    if (!currentUser) throw new Error('user is not logged in')

    const file = payload.file
    const ref = 'public/'

    const uploadTask = await storage.ref(ref).put(file)
    return uploadTask
  } catch (error) {
    return Promise.reject(error)
  }
}

忘れがちなstorage.rules

忘れがちですが、ルールをしていないと権限が無いので保存できずにエラーがでます。 以下のルールは、ログインしていれば誰でも保存できるようにしていますが、 必要に応じて書き換えてください。

service firebase.storage {
  match /b/{bucket}/o {
    match /public/{allPaths=**} {
      allow create: if request.auth != null;
    }
  }
}