Help us understand the problem. What is going on with this article?

FirebaseStorageの使い方・Singleを使って実装する。

More than 1 year has passed since last update.

現在、firebaseのstorageを使ってProfile画像を作っています。

主な使い方は、Firebaseのドキュメントを使って知ることができます。

https://firebase.google.com/docs/storage/?hl=ja:title

FirebaseはStorageは、Pathを Storage.storage().reference() にchildを使って指定します。
child("a").child("b") と書くとaの中のbに画像が保存されます。

今回は、UserProfileを保存したいので、pathは .child("users").child("profile") とします。

let ref = Storage.storage().reference().child("users").child("profile") と変数を持たせれば、画像の取得を楽にすることができます。

はじめに

CocoaPodsでFirebase/Storageをインストールします。

use_frameworks!
pod "Firebase"
pod "Firebase/Storage"

次にFirebase Storageの設定を修正します。
今はAuthorizeしたユーザーしかファイルの読み書きをできないので、誰でもできるように変更します。

画像のアップロード

画像のアップロードは、setDataと言う関数を用いることで使用することができます。
setDataの引数には、保存したい画像のData型とmetaDataを渡します。
metadataは、以下のURLで確認してください。

[https://firebase.google.com/docs/storage/ios/file-metadata?hl=ja]

基本は、nilで大丈夫です。

以下で、UIImageからData型に直すことができます。
0.3と言う数字は、画質に関する情報なのですが、容量の重い画像だとアップロードに時間がかかるので比較的小さい数字でいい気がします。
let imageData = myProfile.jpegData(compressionQuality: 0.3)

戻り値は、metadataとerrorが帰ってくるので、ハンドリングすれば終わりです。

つい数ヶ月前までは、metadata?.downloadURL()で保存先のURLを取得できたのですが現在は使えないようです。

以下がアップロードの処理です。

 func uploadUserProfile(imageData: Data) -> Single<Void> {
        let ref = Storage.storage().reference().child("users").child("profile")
        return Single.create { observer in
            ref.putData(imageData, metadata: nil) { metadata, error in
                if let error = error {
                    observer(.error(error))
                    return
                }
                observer(.success(()))
            }
            return Disposables.create()
        }
    }

画像のダウンロード

ダウンロードには、Data型とURLで取得する2通りの取得方法があります。

Data型で取得する。

Data型は、getDataで取得することができます。引数に、画像のサイズ ' maxSize 'を書きます。
ドキュメントには、1 * 1024 * 1024と書いてありました。
そして、引数には dataerror が帰ってきます。

 func downloadUserProfile() -> Single<Data> {
        let ref = Storage.storage().reference().child("users").child("profile")
        return Single.create { observer in
            ref.getData(maxSize: 1 * 1024 * 1024, completion: { data, error in
                if let error = error {
                    observer(.error(error))
                    return
                }
                guard let data = data else {
                    fatalError()
                }
                observer(.success(data))
            })
            return Disposables.create()
        }
    }

URL型で取得する

現在のプロダクトは、Kingfisherで画像をキャッシュしているのでURLで取得しています。
URLかたで受け取るには、downloadURLで取得でき、引数は必要ありません。
引数には URLerror が帰ってきます。

 func downloadProfileURL() -> Single<URL> {
        let ref = Storage.storage().reference().child("users").child("profile")
        return Single.create { observer in
            ref.downloadURL(completion: { url, error in
                if let error = error {
                    observer(.error(error))
                    return
                }
                guard let url = url else {
                    fatalError()
                }
                observer(.success(url))
            })
            return Disposables.create()
        }
    }

Singleを使うと、流れてくる最初の値のみを流しsuucessとerrorを流すため、APIなど 成功したら結果を、失敗したらエラー情報を返す場合 に便利に使えます。

unochanel
立命館大学経済学部の大学生です。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away