user13036223
user13036223

Reputation:

How to upload the profile image URL to firebase database

When my user signs up, they are using a profile image that goes directly to firebase. The image uploads into firebase storage the properly but once it appears in the database the profile image URL is missing also in the debug area the image link is showing up as optional. What should I change in this code to properly upload the image link into the firebase database?

  if let AuthData = AuthDataResult {
                  print(AuthData.user.email)
                      var dict : Dictionary < String, Any> = [
                        "uid": AuthData.user.uid,
                          "username": self.UsernameTextField.text!,
                      "email": AuthData.user.email,

"ProfileImageUrl": "",
                      ]
    let storage = Storage.storage()
    let storageRef = storage.reference()
    let imageName = UUID().uuidString
    let imageReference = Storage.storage().reference().child(imageName)

    //2. Compress quality
    if let uploadData = self.ProfileImage.image?.jpegData(compressionQuality: 0.5){

    //3. Save image as .jpeg
    let metaDataForImage = StorageMetadata()
    metaDataForImage.contentType = "image/jpeg"

    //4. Add the data to Firebase Storage
    imageReference.putData(uploadData, metadata: metaDataForImage) { (meta, err) in
        if let err = err{
            print(err.localizedDescription)
        } else {
            //5. Retrieving the image URL
            imageReference.downloadURL { (url, err) in
                if let err = err{
                    print(err.localizedDescription)
                } else {
                    //6. Print the complete URL as string
                    let urlString = url?.absoluteString
                    print(urlString)
                }

                Database.database().reference().child("users").child(AuthData.user.uid).updateChildValues(dict, withCompletionBlock: { (error,ref) in
                    if error == nil {
                        print("Done")
                        return
                    }

Upvotes: 0

Views: 756

Answers (2)

Jay
Jay

Reputation: 35657

It appears that all of the code in the question is within the AuthData var.

The issue is caused by one of the key: value pairs within the dict var being an empty string. I'll shorten this up a bit to highlight the issue. Here's the original code with my added comments:

 if let AuthData = AuthDataResult {
    var dict : Dictionary < String, Any> = [
        "uid": AuthData.user.uid,
        "username": self.UsernameTextField.text!,
        "email": AuthData.user.email,
        "ProfileImageUrl": "",  // <--- Profile ImageUrl is an empty string
    ]

    imageReference.putData(uploadData, metadata: metaDataForImage) { (meta, err) in
        if let err = err{
        } else {
            imageReference.downloadURL { (url, err) in
                if let err = err{
                } else {
                    let urlString = url?.absoluteString
                }

                //The ProfileImageUrl key: value pair within the **dict** var is an
                //  empty string at this point, so no url is written.
                let dbRef = Database.database().reference()
                let usersRef = dbRef.child("users").child(AuthData.user.uid)
                usersRef.updateChildValues(dict, withCompletionBlock: { (error,ref) in
                   if error == nil {
                      print("Done")
                      return
                   }
                   //note that if an error occurs, the code silently fails

To fix, populate the dict with the data you want written.

Here's a corrected section of the code which includes error checking and populating the ProfileImageUrl with the download url and then writing it to Firebase.

imageReference.downloadURL { (url, error) in
    if let err = error {
        print(err.localizedDescription)
        return
    }

    guard let validUrl = url else {
        print("url was not valid")
        return
    }

    let urlString = validUrl.absoluteString
    dict["ProfileImageUrl"] = urlString //update the dict with the url

    let dbRef = Database.database().reference()
    let usersRef = dbRef.child("users").child(AuthData.user.uid)
    usersRef.updateChildValues(dict, withCompletionBlock: { error, ref in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        print("Successfully wrote auth data and url")
    })
}

Upvotes: 1

Frank van Puffelen
Frank van Puffelen

Reputation: 598857

My educated guess is that you're writing the user information to the database when the upload hasn't completed, or the download URL hasn't yet been retrieved. Both uploading and requesting the download URL are asynchronous operations, meaning that any code that depends on them being completed needs to be inside the closure that gets executed when the operation completes (or be called from there).

let storage = Storage.storage()
let storageRef = storage.reference()
let imageName = UUID().uuidString
 let imageReference = Storage.storage().reference().child(imageName)

 //2. Compress quality
 if let uploadData = self.ProfileImage.image?.jpegData(compressionQuality: 0.5){

     //3. Save image as .jpeg
     let metaDataForImage = StorageMetadata()
     metaDataForImage.contentType = "image/jpeg"

     //4. Add the data to Firebase Storage
     imageReference.putData(uploadData, metadata: metaDataForImage) { (meta, err) in
         if let err = err{
             print(err.localizedDescription)
         }
         else{
             //5. Retrieving the image URL
             imageReference.downloadURL { (url, err) in
                 if let err = err{
                     print(err.localizedDescription)
                 }
                 else{
                     //6. Print the complete URL as string
                     let urlString = url?.absoluteString
                     print(urlString)

                     // 7. Write the URL to the database here <--
                 }

Upvotes: 0

Related Questions