Firebaseに画像を送信しよう！

こんにちは！🐶

前回は、テキストをFirestoreに送信しました！
今回は、画像を送信してみましょう！

#podをインストールしよう！
はい！ではまず,Firestoreに画像を保存するためにはpodをインストールしなければならないので、以下のコードをpodファイルに記入し、

```
pod 'Firebase/Storage'
```
そしてターミナルに行き、cdしてからpod updateを書きましょう！👇
![スクリーンショット 2021-06-08 15.57.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/c9fc126d-c072-79d6-8db0-778dd58e0abf.png)

#Firebaseに画像を保存できるようにしよう
それでは次に、Firebaseに画像を保存できるようにしましょう！Firebaseのこのアプリのページに行き、左のメニューからStorageを選択しましょう！
![スクリーンショット 2021-06-08 16.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/e0452e41-4211-f99e-f2c0-5197387813ba.png)
そして始めるボタンを選択し、設定画面が出てくるので、次へ＞完了という流れでボタンを押してください！
そうするとStorageが使えるようになりました！
![スクリーンショット 2021-06-08 16.06.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/82ad81b1-e78e-81ac-ab17-0383ae9560bd.png)


#画像を選べるようにしよう！
次は画像を選んで、それを投稿画面のimageViewにセットするところまでしましょう！
まず、storybordに行って、新しくimageViewと投稿画像を選ぶbuttonをセットしましょう！👇
![スクリーンショット 2021-06-08 14.49.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/fdf4e000-384e-8311-6076-56c22f0728c1.png)


はい！そして、PostViewControllerに行き、imageViewの@IBOutletと画像を選ぶbuttonの@IBActionを用意しましょう！👇

```php:PostViewController
import UIKit
import Firebase
import FirebaseAuth

class PostViewController: UIViewController {
    
    @IBOutlet weak var postTextView: UITextView!
    @IBOutlet weak var postButton: UIButton!
    @IBOutlet weak var postImageView: UIImageView!
    //Fierestoreのデータベース
    let db = Firestore.firestore()
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func Post(_ sender: Any) {
        //postTextViewにテキストが入っていたら
        if let message = postTextView.text {
            db.collection("Post").addDocument(data: ["text" : message,"date":Date().timeIntervalSince1970]) { (error) in
                if error != nil {
                    print("送信失敗")
                } else {
                    print("送信成功")
                    //postTextViewを空にする
                  self.postTextView.text = ""
                }
            }
        }
    }
    
    @IBAction func chooseImageButton(_ sender: Any) {
    }
}

```

はい！では @IBAction func chooseImageButtonの中に画像を選ぶコードを書いていきましょう！
今回はUIImagePickerControllerを使って画像を選んでいきます！そのためにUIImagePickerControllerのdelegate（設定）をできるようにextensionにUIImagePickerControllerDelegateを書いてあげてください！👇

```php:PostViewController
    @IBAction func chooseImageButton(_ sender: Any) {
        //imagePicerContoeoller で画像を選択できる
        let imagePicerContoeoller = UIImagePickerController()
        imagePicerContoeoller.delegate = self
        imagePicerContoeoller.allowsEditing = true
        
        self.present(imagePicerContoeoller,animated: true,completion: nil)   
    }
}

extension SignUpViewController:UIImagePickerControllerDelegate,UINavigationControllerDelegate{    
}
```

そして、画像を選ぶようにするには、info.plistの設定も必要なので、info.plistに行き、プラスマークをおし、Privacy - Photo Library Usage Descriptionを選択し追加しましょう！
![スクリーンショット 2021-06-08 15.20.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/862c0923-4403-5c71-dc5b-6c06ab7ea46c.png)

そうすると、画像が選べるようになりました！

![スクリーンショット 2021-06-08 15.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/28873818-9d3d-7e93-066b-e9c0d38d36d8.png)

それでは、extensionの中にコードを書いていきます！

```php:PostViewController
extension PostViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let choosedImage = info[.originalImage] as? UIImage {
            postImageView.image = choosedImage
        }
        dismiss(animated: true, completion: nil)
    } 
}

```

ここれで、画像がちゃんとimgeViewの中に入るようになりました！
![スクリーンショット 2021-06-08 15.37.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/c6511998-fcf6-fbf6-a4bf-2f5ecc4db7d1.png)


#Strageに画像を保存しよう！
それでは次は、FirebaseのStorageに画像を保存したいと思います！
その前にFirebaseStorageをimportしましょう！

そして前回作ったPostViewControllerの @IBAction func Postの中に画像を保存していくコードを書いていきましょう！
全体としては以下のコードになります！

```php:PostViewController
  @IBAction func Post(_ sender: Any) {
        //画像が入っていたら
        guard let postImage = postImageView.image else {return}
        //1画像ファイルが大きすぎるので小さくする
        let uploadImage = postImage.jpegData(compressionQuality: 0.3)
        //2画像の名前を設定
        let fileName = NSUUID().uuidString
        //3保存する場所を指定
        let storageRef = Storage.storage().reference().child("postImage").child(fileName)
        //4storageに画像を保存
        storageRef.putData(uploadImage!, metadata: nil) { (metadate, error) in
            //errorがあったら
            if error != nil {
                print("Firestrageへの画像の保存に失敗")
            }else {
                print("Firestrageへの画像の保存に成功")
                //5画像のURLを取得
                storageRef.downloadURL { (url, error) in
                    if error != nil {
                        print("Firestorageからのダウンロードに失敗しました")
                    }else {
                        print("Firestorageからのダウンロードに成功しました")
                        //6URLをString型に変更して変数urlStringにdainyuu
                        guard let urlString =  url?.absoluteString else {return}
                    }
                }
            }
        }
    }
    
```
やり方としては、
１そのままの画像ファイルでは大きすぎるのでjpegDataで小さくして保存
２画像の名前を設定(fileNmae)
３保存する場所を設定
ここに関しては、実際にStorageを見てみるとわかりやすいです！👇
![スクリーンショット 2021-06-08 18.05.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/6335ebf2-df0d-26d9-08f3-ad45bfeac8c7.png)

Storageを見てみるとpostImageというファイルができています。これを選択し中身を見てみると
![スクリーンショット 2021-06-08 18.06.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/ddc73a33-569c-baf6-b308-ef6261c8d7f4.png)
投稿した画像が保存されています！最初のchild("postImage")が親ファイルとなり、その下のchild(fileName)が子ファイルとなります。
４保存
５画像のURLを取得
先ほど保存した画像を以前作ったPostコレクションの中に入れます。このとき、画像はURLに直さなければならないので、downloadURLでURLを取得します！
６URLをString型に直す
という流れです！

そして６でゲットしたURLは前回作ったPostコレクションに入れてあげます！こうすることで、投稿した際に画像もPostコレクションに届けてあげることができます！

やり方としては、以前作ったfunc savePost()の（）の中に(postImageUrl:String)と書いてあげることで先ほどのURLを引数として使えるように設定します。
そして、postImageUrlも投稿する際に、Postコレクションに入れたいので新しく"image"フィルターを用意してあげます👇

```php:PostViewController
 func savePost(postImageUrl:String){
        //postTextViewにテキストが入っていたら
        guard let text = postTextView.text else {return}
       //imageフィルターを用意し、URLを入れる
        db.collection("Post").addDocument(data: ["text" : text,"date":Date().timeIntervalSince1970,"image":postImageUrl]) { (error) in
            if error != nil {
                print("送信失敗")
            } else {
                print("送信成功")
                //postTextViewを空にする
                self.postTextView.text = ""
            }
        }
    }
```
()の中にpostImageUrl:Stringと書いてあげ、ここに先ほどのURLを入れます！

そしてこの関数を@IBAction func Postの中の画像のダウンロードが終わったタイミングで読んであげましょう！👇

```php:PostViewController
 @IBAction func Post(_ sender: Any) {
           //画像が入っていたら
            guard let postImage = self.postImageView.image else {return}
            //画像ファイルが大きすぎるので小さくする
            let uploadImage = postImage.jpegData(compressionQuality: 0.3)
            //画像の名前を設定
            let fileName = NSUUID().uuidString
            //保存する場所を指定
            let storageRef = Storage.storage().reference().child("postImage").child(fileName)
            //storageに画像を保存
            storageRef.putData(uploadImage!, metadata: nil) { (metadate, error) in
                //errorがあったら
                if error != nil {
                    print("Firestrageへの画像の保存に失敗")
                }else {
                    print("Firestrageへの画像の保存に成功")
                    //画像のURLを取得
                    storageRef.downloadURL { (url, error) in
                        if error != nil {
                            print("Firestorageからのダウンロードに失敗しました")
                        }else {
                            print("Firestorageからのダウンロードに成功しました")
                            //URLをString型に変更
                            guard let urlString =  url?.absoluteString else {return}
                            //ここで呼ぶ。postImageUrlにurlStringを入れることで、URLがsavePostに届く
                           self.savePost(postImageUrl: urlString)
                        }
                    }
                }
            }
        
 
    }
```
という流れになります！
少々複雑ですが、基本やり方を覚えるだけなので、あまり頭を使わなくても良いと思います！


これで画像を無事Firestoreに送信することができました！👇
![スクリーンショット 2021-06-08 21.15.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694910/690299af-b2ad-317c-e323-045c1d91b629.png)



#お疲れ様でした！
今回は、画像の保存について学んできました！これもまた簡単にできちゃいましたね！
次回は、ユーザーのプロフィール設定について学んでいきます！