Cloud Firestoreに保存しているファイルをユーザーが自由にダウンロードできる機能を実装した。公式ドキュメントに手順は記されているのだが、そのままやってもシメのxhr.send()
が作動しなくて詰まった。
CORSの設定
まず、大前提としてブラウザから直接ダウンロードするためには、使用しているCloud Storageのバケットに対してクロスオリジン アクセス(CORS)を構成しておく必要がある。
Google Cloud Console上から、エディタを開いて、cors.json
を作成する。
保存が完了したら、ターミナル上で馴染ませる。
$ gsutil cors set cors.json gs://[APP_ID].appspot.com
CLIを使っていれば、クライアント側の開発環境からも実行できる。
ファイルをダウンロードする
Cloud StorageからファイルURLを取得する
storageRef.child('images/stars.jpg').getDownloadURL().then(function(url) {
・・・
})
正しく動いていれば、URL部分にhttps://firebasestorage.googleapis.com/v0/b/[APP_ID].appspot.com/o/[FOLDER_NAME]%[TOKEN]?&token=[FILE_TOKEN]
のような形式で表示されるはず。
Blobに保存して、aリンクでダウンロード
const xhr = new XMLHttpRequest()
xhr.open("GET", url, true)
xhr.responseType = 'blob'
xhr.onload = () => {
const blob = xhr.response
var objectURL = window.URL.createObjectURL(blob)
var link = document.createElement("a")
document.body.appendChild(link)
link.href = objectURL
link.download = 'DOWNLOAD NAME'
link.click();
document.body.removeChild(link)
}
xhr.send();
外部リンクに直接aタグを叩いてもファイルをダウンロードすることはできないので、一度Blobに保存する必要がある。そのBlobデータを叩けば、なんなくファイルがダウンロードされる。