FIREBASE CRUD sauvegarder une image de profil

FIREBASE CRUD sauvegarder une image de profil

Etape 6

Pour l'instant l'utilisateur est défini avec son nom, prénom, adresse mail, et uid.

LES BASES de DONNEES :

Les données de l'utilisateur sont stockées dans la database "Firestore" de Firebase.

Les images seront stockées dans la database "Storage" de Firebase, avec une adresse "url".

Cette adresse "url" indique l'emplacement de l'image. Elle est ajoutée aux données de l'utilisateur dans la database "Firestore".

Les deux bases associent les données en fonction de l'"uid" de l'utilisateur.

LA SAUVEGARDE DES IMAGES DANS STORAGE :

Mettre à jour le modèle "User.swift" en ajoutant la propriété "profilImageUrl"

var profilImageUrl: String?

init(....
     profilImageUrl = data["profilImageUrl"] as? String
}

Créer un nouveau fichier "FireStorage.swift".

Comme pour "Database", définir un chemin d'accès au stockage d'images :

var base = Storage.storage().reference()

Et l'accès au dossier image (profilImageUrl) de l'utilisateur (uid), avec une fonction qui renvoi le chemin :

//chemin du stockage : base.child(uid) = dossier storage de l'user(uid)     .child("profilImageUrl"= dossier profilImage
    func userProfile(_ uid: String) -> StorageReference {
        return base.child(uid).child("profilImageUrl")
    }

Définir une méthode "sendImageToFirebase" qui aura en paramètre une référence de stockage, une image, et une complétion pour récupérer une "url" en String.

Envoyer l'image avec la méthode de Firebase "putData()" :

ref.putData(uploadData: Data, metadata: StorageMetadata?, completion: ((StorageMetadata?, Error?) -> Void)?)
typealias ImageUploadCompletion = (_ urlString: String?, _ error: Error?) -> Void

    func sendImageToFirebase(_ ref: StorageReference, _ image: UIImage, completion: ImageUploadCompletion?) {
        //transformer l'image en data, ici jpeg compresser à 30%
        guard let data = image.jpegData(compressionQuality: 0.25) else { return }
        //envoi des data sur storage avec la reference ref
        ref.putData(data, metadata: nil) { (storeData, error) in
            if error != nil {
                print(error!.localizedDescription)
                completion?(nil, error)
            }
            if storeData != nil {    //il y a des data
                ref.downloadURL { (url, error) in     //récupération de l'url
                    if error != nil {
                        completion?(nil, error)
                    }
                    if url != nil {
                        completion?(url!.absoluteString, nil)   //transforme l'url en string
                    }
                }
            }
        }
    }

L'url de l'image a été récupéré. Pour l'ajouter au profil Firestore de l'utilisateur :

Dans "FireDatabase.swift" créer une fonction pour mettre à jour l'utilisateur, avec la méthode propre à Firebase = "updateData() :

func updateUser(_ uid: String, data: [String: Any]) {
        usersCollection.document(uid).updateData(data)
    }

La méthode "update" met à jour ce qui est nécessaire, "setData" créé en effaçant tout.

Voilà, il reste a créer une méthode dans le "profilController" pour appeler ces fonctions :

func updateProfile(_ image: UIImage) {
        guard let uid = FireAuth().myId() else { return }  //récupération de uid
        let ref = FireStorage().userProfile(uid) //définit un emplacement pour l'user
        FireStorage().sendImageToFirebase(ref, image) { (url, error) in   //envoi l'image et récupére l'url
            if let urlString = url {
                FireDatabase().updateUser(uid, data: ["profilImageUrl": urlString])   //met à jour le profil = ajout url
            }
        }
    }

Avant de tester, bien vérifier que la database "Storage" est active dans votre projet Firebase. Que les règles de sécurité soient bien renseignées.

Cette méthode est appelée dans un bouton "Valider", (ou une action d'alerte,...) :

@IBAction func validateButton(_ sender: UIButton) {
        updateProfile(profilImage.image!)
    }

L'uid de l'utilisateur est souvent demandé à Firebase, il peut être stocké dans une constante.