10
8

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-12-27

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

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

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など 成功したら結果を、失敗したらエラー情報を返す場合 に便利に使えます。

10
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8