0

Hey I am trying to retrieve the user image saved in the firebase storage but I am using this storage path (the folder of profile pictures in firebase) as a string(child path) to update the user image. When the user profile updates there are no errors this code just didn't update the user image as I expected what am I missing here that will allow me to successfully my user image and solve my problem ?

                            var spaceRef = Storage.storage().reference()
                        let storagePath = "gs://tunnel-vision-bc055.appspot.com/images/space.jpg"
                        spaceRef = Storage.storage().reference(forURL: storagePath)
                       let reference = spaceRef.child("profilePic")

                        // UIImageView in your ViewController
                        let imageView: UIImageView = self.ProfileImage

                        // Placeholder image
                        let placeholderImage = UIImage(named: "image/jpeg")

                        // Load the image using SDWebImage
                        imageView.sd_setImage(with: reference, placeholderImage: placeholderImage)
                            // Uh-oh, an error occurred!
                            return
                          }
  • Check if this solves your issue: https://stackoverflow.com/a/59872820/2781088 – Mohit Kumar Jan 28 '21 at 14:01
  • What call is the error referring to? – Dan Abnormal Jan 28 '21 at 21:33
  • this line right here let user = User(ProfileImage: ProfileImage) @DanAbnormal –  Jan 29 '21 at 16:33
  • And what does the User class look like? – Dan Abnormal Jan 29 '21 at 16:36
  • let imageView: UIImageView = self.ProfileImage @DanAbnormal –  Jan 29 '21 at 16:48
  • I meant the User class, as in User(ProfileImage: ProfileImage). – Dan Abnormal Jan 29 '21 at 16:51
  • let user = Auth.auth().currentUser if let user = user { let uid = user.uid let email = user.email let photoURL = user.photoURL // ... } @DanAbnormal –  Jan 29 '21 at 17:09
  • The profile image is a string that is attached to firebase that I need to retrieve in order to update the profile user image @DanAbnormal –  Jan 29 '21 at 17:10
  • Yes, I understand that. But you are mixing class variables (self.ProfileImage) with local constants (let ProfileImage). You then use your local constant ProfileImage to initialize another local constant let user of type User. And I still have not seen this User class, that according to your code takes ProfileImage (string) as a parameter. – Dan Abnormal Jan 29 '21 at 17:13
  • btw let imageView: UIImageView = self.ProfileImage will never change the imageView's image. You need to assign the imageView property image (imageView.image) with a UIImage, not a string. There are tons of questions about this on SO. This is one: https://stackoverflow.com/questions/39122918/how-to-load-uiimage-from-url – Dan Abnormal Jan 29 '21 at 17:18
  • Did you follow a tutorial online? If so, which one? Maybe I can help by looking at it. – Dan Abnormal Jan 29 '21 at 17:23
  • okay. but what about the let user= User(ProfileImage: ProfileImage) because that's my real issue @DanAbnormal –  Jan 29 '21 at 17:25
  • My question is exactly that: what is this User class/object? Where does it come from? Did you create it yourself? Can you show me its declaration? – Dan Abnormal Jan 29 '21 at 17:28
  • ProfileImage is the UIimageView I tried using this let ProfileImage = self.ProfileImage.image but the error still exist @DanAbnormal –  Jan 29 '21 at 17:40
  • You said earlier the error refers to let user = User(ProfileImage: ProfileImage). I then asked what this User class/object looks like. But yet I have not seen it. I think there are many errors here. Are you sure you fully understand the code you are trying to implement? If not you will never make this work. – Dan Abnormal Jan 29 '21 at 17:50
  • I am new to coding this is why I need help retrieving the data from firebase @DanAbnormal –  Jan 29 '21 at 18:22
  • 1
    There are a number of issues with the code in the question; the big picture is the actual image should be stored in Firebase Storage (or another hosting site), and the path to that image is what's stored in the Firebase Realtime Database. The code in the question is a bit nonsensical naming wise as a `ProfileImage` is very different than a `ProfileImageURL` here `let ProfileImage = value?["ProfileImageUrl"] as? String ?? ""`. Please review the guide [Storage](https://firebase.google.com/docs/storage/ios/create-reference) – Jay Jan 29 '21 at 21:46
  • the image is stored in firebase storage but storage only allow me to update the user image using an url and that's a problem because it only allow me to access one image and that's defeating my purpose I need multiple users able to access their user images w/o seeing the same image @Jay –  Jan 29 '21 at 23:47
  • Correct. So in the Realtime Database, within each users node, you would store the path their image in Storage. e.g. for user 0 */users/uid_0/path_to_uid_0_image* and then for user 1, */users/uid_1/path_to_uid_1_image* – Jay Jan 30 '21 at 16:33

1 Answers1

1

This will not be the answer to all your issues, but hopefully some of them.

First of all, in Swift, variables and constants starts with a lowercase letter. Classes with uppercase. For example, your ProfileImage should be profileImage. For clarity, when I type profileImage I refer to your ProfileImage.

Now, types. You have a constant profileImage in the code you posted. This is of type String. You set the value of the key "ProfileImageUrl" to it. I would change it's name to profileImageURL.

Then (according to one of your comments) you are calling self.profileImage

let imageView: UIImageView = self.profileImage

Since you're not seeing any errors I assume you also have a class property called profileImage of type UIImageView.

The line

// let user = User(ProfileImage: ProfileImage)

will not help you. As far as I understand from the code you posted - and what you are trying to achieve - you may as well delete it. Or comment it (//) as I did above.

What you want to do is to set an imageView's image.

For this you need to do

imageView.image = image

And to be able to do that you need an imageView and an image. If you don't know how to create an imageView, search for answers here on SO.

You can then create the image from the url you get from Firebase and set it to the imageView. Kind of like this

let profileImageURL = value?["ProfileImageUrl"] as? String ?? ""
let url = URL(string: profileImageURL)

DispatchQueue.global().async {
    guard let data = Data(contentsOf: url) else {return} // if url is nil, return block is executed and code below is not
    DispatchQueue.main.async {
        self.imageView.image = UIImage(data: data)
    }
}
Dan Abnormal
  • 1,188
  • 11
  • 21
  • Super good and clear answer; however, the code `Data(contentsOf: url)` won't apply if the OP is using [Firebase Storage](https://firebase.google.com/docs/storage/ios/download-files) which it appears they are *retrieve the user image from firebase*. Also, I would guess the OP wants to create a user object with the users image so `let user = User(profileImage: userImage)' would make sense for this use case. Very helpful! – Jay Jan 29 '21 at 21:53
  • Thanks @Jay! I think you’re right. I just could not make sense of it all at that moment. I will consider updating this answer – Dan Abnormal Jan 29 '21 at 21:59
  • yeah jay was right Data contents didn't work it only gave me another error Call can throw, but it is not marked with 'try' and the error is not handled @DanAbnormal –  Jan 29 '21 at 23:44