FirebaseのStorage機能を使うと、無料でGoogle Cloud Storageを5GB分利用できる。Golangからファイルをアップロード/ダウンロードする方法を以下に記す。
事前準備
Firebase Storageの設定
メニューから「Storage」を選ぶ 「スタートガイド」をクリック セキュリティ保護ルールの説明を読んだら「次へ」 必要に応じてロケーションを変更して、設定を完了する。ロケーションは後から変更できないので注意。 設定が完了。ここのStorageのBucketのURLは後で参照するのでメモっておく。 ## アクセス用Credentialの取得 すでにサービスアカウントの秘密鍵を生成している場合はそちらを使用してください。秘密鍵を生成していない場合は新しく作成します。
プロジェクトの設定を開く 「サービスアカウント」から「新しい秘密鍵の生成」を行う。 「キーを生成」すると、生成された秘密鍵のJSONファイルがダウンロードされるので、適当なファイル名(ここでは`storage-exp-key.json`)に変更して適当な場所に置く。Admin SDKのインストール
go get
でFirebase Admin SDKをインストールする。
go get firebase.google.com/go
Firebase Admin SDKを初期化する
config := &firebase.Config{
StorageBucket: "storage-exp.appspot.com",
}
opt := option.WithCredentialsFile("storage-exp-key.json")
app, err := firebase.NewApp(context.Background(), config, opt)
if err != nil {
log.Fatalln(err)
}
先ほど作ったサービスアカウントのキーを使って、Firebase SDKの初期化を行う。その際、StorageのBucketのURLを指定する。StorageのBucketのURLは、Storage画面のここで確認できる。
StorageのBucketを取得する
client, err := app.Storage(context.Background())
if err != nil {
log.Fatalln(err)
}
bucket, err := client.DefaultBucket()
if err != nil {
log.Fatalln(err)
}
app.Storage()
でStorage操作用のクライアントを取得し、さらにそのクライアントのDefaultBucket()
を呼ぶことで、上で設定したBucketを取得できる。Blazeプラン以上の場合はBucketを複数追加して、Default Bucket以外のCustom Bucketを使うこともできるが、無料プランの場合はDefault Bucket以外は利用できない。
ここで返されるbucket
はGoogle Cloud StorageのBucketHandleなので、ここから先はGoogle Cloud StorageのAPIを利用していくことになる。Firebaseのサービスキーを使ってすでに認証も完了した状態になっているのでそのままAPIを叩ける。
ファイルをアップロードする
Cloud Storage APIを使ってファイルをアップロードしてみる
localFilename := "sample.txt" // ローカルのファイル名
remoteFilename := "sample.txt" // Bucketに保存されるファイル名
contentType := "text/plain"
ctx := context.Background()
writer := bucket.Object(remoteFilename).NewWriter(ctx)
writer.ObjectAttrs.ContentType = contentType
writer.ObjectAttrs.CacheControl = "no-cache"
writer.ObjectAttrs.ACL = []storage.ACLRule{
{
Entity: storage.AllUsers,
Role: storage.RoleReader,
},
}
f, err := os.Open(localFilename)
if _, err = io.Copy(writer, f); err != nil {
log.Fatalln(err)
}
defer f.Close()
if err := writer.Close(); err != nil {
log.Fatalln(err)
}
ローカルにあるsample.txt
の内容を読み込んで、Bucket上に同じくsample.txt
という名前のファイルで保存する。contentType
はテキストなのでtext/plain
を、動作確認で混乱がないようにキャッシュはno-cache
にした。アクセスは全員がRead
することができるように指定している。この辺りの設定は実際の使用用途に合わせて適宜書き換えて使う。
プログラムを実行すると、ファイルがアップロードされる。アップロードされたファイルはFirebase ConsoleのStorage
画面で確認できる。
ファイルをダウンロードする
Bucketにアップロードしたファイルを今度はダウンロードしてみる。
rc, err := bucket.Object(remoteFilename).NewReader(ctx)
if err != nil {
log.Fatalln(err)
}
defer rc.Close()
data, err := ioutil.ReadAll(rc)
if err != nil {
log.Fatalln(err)
}
log.Printf("Downloaded contents: %v\n", string(data))
ファイル名指定でBucketからコンテンツをダウンロードして表示してみる。やり方は通常のCloud StorageのAPIを利用する時と変わらない。
ファイルをブラウザからダウンロードする
ルールの設定
デフォルトの設定ではStorageにアップロードされたファイルは認証済みのユーザしかReadもWriteもできないようになっている。今回は認証していないユーザでもダウンロード(read)できるように変更する。(writeは引き続き、認証済みのユーザのみ)
allow read;
allow write: if request.auth != null;
Javascriptでダウンロード用のURLを発行する
<script src="https://www.gstatic.com/firebasejs/6.3.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.3.1/firebase-storage.js"></script>
// Your web app's Firebase configuration
var firebaseConfig = {
// Consoleで表示されているConfigをそのままコピペする
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
var storage = firebase.storage();
storage.ref('sample.txt').getDownloadURL().then(function (url) {
console.log(url);
})
StorageのAPIを利用するには、firebase-storage.js
の読み込みが必要なので忘れないように注意。getDownloadURL()
でダウンロード用のURLを取得できる。
curl "https://firebasestorage.googleapis.com/v0/b/storage-exp.appspot.com/o/sample.txt?alt=media&token=..."