FirebaseStorageの画像をSDWebImageで表示しようとして詰まった話

## 目次

- 自己紹介
- 最近作ったアプリ Lily
- Firebase StorageのTips
- まとめ

---

## 自己紹介

* 筋肉エンジニアとしてSpajamで頭角を表す
* JX通信社でNewsDigestというニュースアプリを作っています
* 個人でもアプリ作ります

<img width="294" alt="スクリーンショット 2017-08-28 17.18.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/fab8c03d-6abd-bb18-03ce-a6a75b8c8108.png">


---

## 最近作ったアプリ(個人)

### ダイエット動画で継続できる！習慣化アプリ-Lily

![FullSizeRender 4.jpg](https://qiita-image-store.s3.amazonaws.com/0/111366/bc4a3348-355e-9108-24b8-30c7524cc716.jpeg)

https://itunes.apple.com/jp/app/id1261813918?mt=8

---

## Firebase

--- 

## Firebaseを使う理由

* 個人開発なのでmBaas
* RealtimeDatabaseなのでFirebase
* Cloud Functionでプッシュ通知打てそうなのでFirebase

---

## しかし、画像の処理で少し詰まる。。。

---

## いつもやる画像処理

```swift
imageView.sd_setImage(with: thumbnailUrl)
```

---

## FirebaseStorageではこれができなかった

---

## 理由

* ファイルのダウンロードURLしかわからない

---

## Firebase Console

<img width="1007" alt="スクリーンショット 2017-08-28 17.34.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/432d3cbb-78d6-467b-9e1d-ff37802c90a8.png">

---

<img width="306" alt="スクリーンショット 2017-08-28 17.34.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/52e8f582-cf4e-296d-54ad-358cf86ad5ea.png">

---

## ダウンロードURLを叩いてみると

<img width="399" alt="スクリーンショット 2017-08-28 17.37.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/e20775f7-fa0b-6dba-c9f6-7e518eee8bd1.png">

https://firebasestorage.googleapis.com/v0/b/lily-ios-debug.appspot.com/o/profile%2FazUN6bPT6DwWyq1BIybPsDzE0fd52.jpeg?alt=media&token=0686826a-6c62-4886-92d7-86d2425d51c9

jpgファイルがダウンロードされてしまった。

**ちなみにこのURLをSDWebImageの以下でいう　`thumbnailUrl` にセットしても画像が表示されませんでした。。**

```swift
imageView.sd_setImage(with: thumbnailUrl)
```

---

＿人人人人人人人人人＿
＞ **SDWebImageが使えない** ＜
￣Y^Y^Y^Y^Y^Y^Y^Y^Y￣

---

## しかし、FirebaseUIがあった

---

## FirebaseUI

<img width="1039" alt="スクリーンショット 2017-08-28 17.51.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/e9c3567a-20d1-f655-a859-b0f3652f1b28.png">

https://github.com/firebase/FirebaseUI-iOS

---

* cocoapods

```rb
pod 'Firebase/Storage'
pod 'FirebaseUI/Storage'
```

---

```swift
import Firebase
import FirebaseStorage

static func setImage(uid: String, imageView: UIImageView?){
        let storageRef = Storage.storage().reference()
        let ref = storageRef.child("profile/\(uid).jpg")
        imageView?.sd_setImage(with: ref, placeholderImage: nil)
    }
```

* SDWebImageが拡張されていて、firebaseStorageの参照を引数にあげたら、よしなにやってくれる

```swift
imageView?.sd_setImage(with: ref, placeholderImage: nil)
```
---

## ここまでのまとめ

* SDWebImageネイティブなので、画像の処理方法、それしかない僕
* FirebaseStorageだとファイルをダウンロードしちゃうURLしかないからいい感じでキャッシュするのは無理かと思ったけど
* FirebaseUIというライブラリがなんとかしてくれた

---

## 追記(ここで急展開)

---

## Twitterの様子

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Firebase Storage、アクセス許可周りをpublicにすればパーマリンク得られたような気がする <a href="https://twitter.com/hashtag/potatotips?src=hash">#potatotips</a></p>&mdash; 🙌🐼ひらり🐼🙌 (@hiragram) <a href="https://twitter.com/hiragram/status/902119719011926016">2017年8月28日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">FirebaseStorage に上げた画像が簡単に取ってこれない話、自分のアプリでは「別に public でもいいじゃんこれ」と結論付けて、FirebaseStorage の設定自体を変えたなぁw そうすると楽勝でした。 <a href="https://twitter.com/hashtag/potatotips?src=hash">#potatotips</a></p>&mdash; tsuyoyo (@tsuyogoro) <a href="https://twitter.com/tsuyogoro/status/902120781286580224">2017年8月28日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

---

## なんやて！？

---

## downloadURLがダメなのではなかった

---

## 原因

* ファイルのタイプが `application/octet-stream` だったこと

![スクリーンショット 2017-08-30 12.38.35.png](https://qiita-image-store.s3.amazonaws.com/0/111366/deec791f-f724-84d8-1ac7-c7b8d4c50b17.png)

この場合のdownloadURLは飛んでみるとわかりますが、ファイルをダウンロードしちゃいます。

https://firebasestorage.googleapis.com/v0/b/lily-ios-debug.appspot.com/o/profile%2FazUN6bPT6DwWyq1BIybPsDzE0fd52.jpeg?alt=media&token=0686826a-6c62-4886-92d7-86d2425d51c9

→ これが `image/jpeg` になってれば、downloadURLはSDWebImageで使える形になる。

---

## アップロードするときのTips

アップロードするときにやることがあった！

### meta.contentTypeを指定する

```swift
let ref = storageRef.child(key)
let meta = StorageMetadata()
meta.contentType = "image/jpeg" // <- これ！！
ref.putData(data, metadata: meta) { metadata, error in
    metadata!.downloadURL()! // このURL
}
```

タイプが `image/jpeg` になるとFirebase StorageのConsoleに以下のように表示されます。ここで画像も見れるようになるんですね！

<img width="286" alt="スクリーンショット 2017-08-30 20.13.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/111366/4fe29be2-c87b-07dc-b8db-954bc7ff10c0.png">

リンクを押すとダウンロードされずに、そのままブラウザで見れます。

https://firebasestorage.googleapis.com/v0/b/lily-ios-debug.appspot.com/o/profile%2FzUN6bPT6DwWyq1BIybPsDzE0fd52.jpeg?alt=media&token=c9682120-051f-4fac-9a31-81c077f2d08d


---

## ということで

ブラウザでURL叩いても見れた！

これでSDWebImageにurlをセットしていつも通りに画像が見れました！

みなさんご指摘ありがとうございます。Tipsが得られました！

---

## 結論

* firebaseUIを使ってRefで画像を表示してもいいし、
* アップロード時の指定に注意していつも通りSDWebImageを使って表示することもできる

知って入れば後者の方が簡単な気がします。