【Firebase】Storage に画像を保存しアプリで表示する手順

今回は、Firebase の一機能である Cloud Storage を使って Swift 言語で画像をアップロードする手順について紹介します。

※Firebase のプロジェクト作成、SDKインストールや初期設定のプログラムなどについては下記の記事の見出し(1)〜(2)の内容をご参考ください

【Firebase】Storage に画像を保存しアプリで表示する手順

Firebase/Storage のインストール

Podfile vi で開き、Firebase/Storage の記載を追加します。

$ vi Podfile
〜
〜
pod 'Firebase/Storage'

:wq で保存したら pod install を実行します。

$ pod install

※環境によって、新しい Firebase のライブラリをインストールすると Xcode でリンクエラーが発生することがあります。そういった場合は以下のように一度ライブラリをクリアしてインストールし直すと解消する場合があります。

$ pod deintegrate
$ pod install

Firebase コンソールの Storage 画面を確認

Firebase プロジェクト作成後、コンソール画面の Storage から「始める」をクリックします。

セキュリティ保護ルールについての説明が表示されます。

セキュリティルールについては今回は触れませんが、以下のデフォルト設定では、read、write ともに Firebase Authentication による認証が必要という意味になります。

次へ進むと、ロケーションの設定画面が表示されます。ロケーションの設定はこの一度限で変更不可ですので間違ったロケーションを選ばないように注意しましょう。

東京(asia-northeast1)か大阪(asia-northeast2)が候補となると思いますが、東京を選択しておくのが無難です。

ロケーションの選択についてはこちらのQiita記事が参考になります。

「完了」をクリックすると Storage の Files タブのメニューが表示されます。

Storage は MacOS・Windows・Linux などと同じようにディレクトリの階層構造となっています。

赤い四角で囲んだ部分がこの Storage のルートディレクトリとなります。

gs://[プロジェクト名].appspot.com
[プロジェクト名].appspot.com/ 以下に任意のディレクトリ(以降フォルダとします)を生成し、ファイルを格納していくことになります。

フォルダの作成と画像の格納

コンソール画面からフォルダを作成し、画像を格納して見ましょう。

フォルダ追加ボタンをクリックし、フォルダ名を入力後「フォルダを追加」をクリックします。

test フォルダが作成されたことが確認できます。

続いて test フォルダをクリックし中身を参照します。当然まだ何も入っていません。

「ファイルをアップロード」をクリックし任意の画像を選択しアップロードしてみましょう。

今回は test.png という画像をアップロードしました。

ファイル名、サイズ、画像の種類、最終更新日が確認できます。

それでは、ブラウザから画像にアクセスしてみましょう。

test.png をクリックすると右側に画像の詳細情報が表示されますので、test.png のリンクをクリックしてみましょう。

以下のように画像にアクセスできていることが確認できるはずです。

Swift で画像をアップロードする

いよいよ本題です。

Storage の機能を使うには FirebaseStorage をインポートします。

import FirebaseStorage

先程の test.png を同じ場所にアップロードするには以下のような流れとなります。

まず、Firebase Storage のルートフォルダへの参照を以下のように取得します。

let storage = Storage.storage()
let reference = storage.reference()

続いて、画像のアップロードパスの参照を取得します。

let path = "gs://[プロジェクト名].appspot.com/test/test.png"
let imageRef = reference.child(path)

画像データは、ローカル画像を URL 型でアップロードする方法と、UIImage から Data 型に変換して バイナリデータとしてアップロードする方法の2通りがあります。

URL指定でアップロードする場合

putFile を使ってアップロードします。

let url = URL(string: "ローカル(端末)の格納場所")
let uploadTask = imageRef.putFile(from: url)
Data指定でアップロードする場合

putData を使ってアップロードします。画像は予め UIImage から Data へ変換しておきます。

guard let data = image.pngData() else {
    return
}
let uploadTask = imageRef.putData(data)

putFile・putData ともに即座にアップロードは完了しないため、戻り値として取得できる StorageUploadTask を使って、成功 or 失敗を監視する必要があります。

アップロードを監視するには、StorageUploadTask の observe メソッドを使用します。

成功の監視

observe に .success を与えるとアップロード成功を監視できます。

var downloadURL: URL?
uploadTask.observe(.success) { _ in
    imageRef.downloadURL { url, error in
        if let url = url {
            downloadURL = url
        }
    }
}

成功するとクロージャが実行されるので、クロージャ内で画像の参照(imageRef)からダウンロードするURLを取得できます。

URLは後で表示する時に使用するので保持しておきましょう。

失敗の監視

observe に .failure を与えるとアップロード失敗を監視できます。

uploadTask.observe(.failure) { snapshot in
    if let message = snapshot.error?.localizedDescription {
        print(message)
    }
}

アップロードした画像を表示する

アップロードが成功したら、StorageReference.downloadURL で取得した URL を使って画像をダウンロードして表示することができます。

do {
    let data = try Data(contentsOf: url!)
    return UIImage(data: data)!
} catch let error {
    print("Error : \(error.localizedDescription)")
}

URL から 画像の Data を取得、UIImage を生成しています。このあたりは特に変わったことはしていません。

ちなみに URL から直接 UIImageView にセットできるライブラリ(AlamofireImageNukeなど)もあるので導入を検討しても良いでしょう。

以上

【おすすめの関連記事】

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です