User Profile Picture
Instagram Firebase
Now that the necessary Firebase SDKs have been installed and the user authentication step is complete, let's dive into the code that allows more data persistence. First we'll implement the feature that saves a username into Firebase Database. Then we move onto using UIImagePickerController to allow the user selection of the profile image in our application. Lastly, we upload the image into Firebase Storage, which conveniently gives us back a URL for retrieval later. Finally we take this URL and save it onto our user along with their username.

Comments (112)
johnrm9
6 years ago
For those who like a dark Mac OS menu bar and Dock (check box in System Preferences/General): Here's an AppleScript one-liner to toggle the dark mode: tell application "System Events" to tell appearance preferences to set dark mode to not dark mode Enjoy!
johnrm9
6 years ago
Here's an interesting String extension to check email syntax I gleaned from Stack Overflow: extension String { public var isEmail: Bool { let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) let firstMatch = dataDetector?.firstMatch(in: self, options: .reportCompletion, range: NSRange(location: 0, length: length)) return (firstMatch?.range.location != NSNotFound && firstMatch?.url?.scheme == "mailto") } public var length: IndexDistance { return self.characters.count } } @objc func handleTextInputChange(_ sender: UITextField){ guard let email = emailTextField.text, let username = usernameTextField.text, let password = passwordTextField.text else { return } let isEmailValid = email.isEmail // valid email syntax? let isUsernameValid = username.length > 0 // length is same as characters.count let isPasswordValid = password.length > 0 let isFormValid = isEmailValid && isUsernameValid && isPasswordValid signUpButton.isEnabled = isFormValid signUpButton.backgroundColor = signUpButton.isEnabled ? UIColor(r: 17, g: 154, b: 237) : UIColor(r: 149, g: 204, b: 244) } I like to put @objc on Objective-C selector handlers, making them easy to spot. (I did this when a earlier version of Xcode complained about marking the handler private.) The parameter, _ sender: UITextField is not needed, but I can tell which text field triggered this handler by setting the tag property for each text field, e.g., in the block closure set up - let textField = UITextField() textField.tag = 0 // or 1, 2 or something... textField.addTarget(self, action: #selector(handleTextInputChange(_:)), for: .editingChanged) Thanks
Tokyojogo
5 years ago
Email syntax, email already in use and weak password is already handled by firebase. All you need to do is create a switch statement to display the error for each one.
tomxue
6 years ago
If you haven't noticed, the image for a button will always be rendered as a template image by default. You can try that out in a storyboard as well. The reason is that when you set an image in a template rendering mode, you can adjust the tint color however you want, that becomes really handy when you need it.
Slava Nagornyak
6 years ago
Hi Brian! Just wanted to notice, that UIImagePickerControllerEditedImage and UIImagePickerControllerOriginalImage are String constants, so you don't have to type it like strings each time. It's better to use constants because autocomplete will save a little piece of your time and also there will be no chance to make a mistype. And one more thing, it's better to use UUID instead of NSUUID unless you don't have a good reason for it. It's what Apple does always say. And of course, thank you for this course!
Brian Voong
6 years ago
alpertabak
6 years ago
Thanks for information. Those who dont know how to use UUID like me, let filename = UUID().uuidString.lowercased() and the output is like this "0e9afda9-277a-4b92-b15f-93295e17173d "
Tokyojogo
5 years ago
Wouldn't it better to use uid (from firebase) instead? What is the advantage of using UUID()?
David Luong
6 years ago
Hi Brian, Do you ever get this funky message in the console: '[Generic] Creating an image format with an unknown type is an error'? I've ran into this message in the past and it has caused some weird issues, but some hacking around fixed it. Do you know exactly why this happens and is there an actual fix for it?
Brian Voong
6 years ago
David Luong
6 years ago
Oh ok, that's very interesting. I ran into the issue yesterday when I was using the default photos that are in the 'Moments' album in the simulator. Basically, when I tried select the photo using UIImagePicker, the ImageView becomes black. It might have been a simulator problem because it did not happen like that at first, only happened after I re-ran it a couple of times. Threw it on my iPhone 6s instead and it works just fine. It's a strange bug that has been happening for awhile.
Jesus Adolfo
6 years ago
Woah firebase is really cool. Thanks for spreading the knowledge. It is hard to believe that you're running a one man operation here.
Brian Voong
6 years ago
omari
6 years ago
Hello Brian, if the user picks an image he can change it before signing up. But how can the user delete the image after selecting one ?
Brian Voong
6 years ago
Dan Boyle
6 years ago
Hey Brian... I am adding some of this functionality to an app I an building. When I choose a picture from my simulators photo library (it is in jpg format)... I get this in the console: [Generic] Creating an image format with an unknown type is an error But when I created the editedImage and the originalImage... I downcasted them as UIImage which is a type right? Any ideas?
Brian Voong
6 years ago
Robert Barta
6 years ago
The response comes kinda late as I joined the course recently, but I got the same problem in a few of my projects and it always resulted from the images being too large / too high resolution. Downsizing them in the UIJPGRepresentation call actually solved the problem for my cases.
kenbrlow+lbta
6 years ago
Hey Brian, Tutorials are going great, had a quick question though. When it comes to firebase security, are you going to adjust the rules of the firebase instance to show good security practices? Just wondering what would be some good settings to implement. Thanks! Ken
Brian Voong
6 years ago
edward
6 years ago
Hey Brian, Would it not be better to use the user's uid for the profile image file path? You can then lock it down with security rules
ericha1981
6 years ago
Brian, I am having an issue with profile image selected from the image picker. Instead of having the image "fit" into the plusPhotoButton I seem to get it literally in its original size covering half of the app. Somehow 140 by 140 constraint is not holding. Why is this? While I may find a fix myself I wonder why mine doesn't work when the code is the same.
Brian Voong
6 years ago
ericha1981
6 years ago
Brian, No. You don't have that anywhere, on screen or in project. Only bounds you have is masksToBounds after the cornerRadius and I have those too. Weird.
turtle0001
6 years ago
I'm also having the same issue. I check the sample project and compared Brian's code on the one I created. After checking the code and rebuild the app the issue still appeared.
turtle0001
6 years ago
I think I found the problem? I to check your anchor extension and compare it to Brian. I solved mine by copying his anchor and replaced what I've done. And now it works.
fahad
6 years ago
Hi Brian, I have problem saving the user's state...Every time i run the app, it forces to login/signup to see the feed page; unlike your version where it goes straight up to the app.
Brian Voong
6 years ago
fahad
6 years ago
No. It's an old project I've been working on, but i'm pretty sure i followed the instructions carefully.
Brian Voong
6 years ago
fahad
6 years ago
Thanks a lot, Brian.
fabien040
6 years ago
@all - I was getting lots of messages from Firebase in the debug window. Capabilities: Enabling keychain sharing on removes all the messages. Don't ask me why.
Mickaz89
6 years ago
Hi , i work with ios 11 and when i try to acces to the photo library , she don't ask me the permission to access , it is normaly ? thanks
emircav
6 years ago
Getting the same error, have you found a fix?
Redoine Aito
6 years ago
I'm getting the same error
awaghmare
5 years ago
Starting in iOS 11, you don't have to ask the user permission anymore to allow them to select an image from their photo library. This is due to some under the hood changes by Apple: the app is only provided information about selected images and can no longer see all the images in the user's photo library. See this link for more details: https://stackoverflow.com/questions/46404628/ios11-photo-library-access-is-possible-even-if-settings-are-set-to-never
smiller193
6 years ago
Is anyone having an issue with the input accessory view getting stuck at the bottom? When exiting comment screen
Daniel Keinan
6 years ago
Is it possible to show a Direct Message Feature in new lessons?
Brian Voong
6 years ago
Apurva Raj
6 years ago
Suggestions for next videos Insta story Photo editing (more features) Refactor code
smiller193
6 years ago
I second this suggesstion even though it probably wont happen
Fangda Han
6 years ago
Hi, Brain, I found this video is hard to navigate, a little suggestion is to transfer these videos to some more user-friendly video source like youtube.
Adam El-Kadi
5 years ago
Hey Brian, do you have any apps on the app store. I just want to see how a next level programers app would be like :P
Nikhil Patil
5 years ago
While uploading the image, i'm getting this error, please help Successfully created a user, 5GKhQ456C2YHXNg1Xw8MLXSgxiH3 2017-10-14 17:08:19.238132+0100 InstagramFirebase[63853:14007920] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'No default Storage bucket found. Did you configure Firebase Storage properly?'
Brian Voong
5 years ago
Nikhil Patil
5 years ago
Actually i did opened it but the reason was plist file which i got initially from firebase does not have <STORAGE_BUCKET - URL> configured, so what i did was match my plist file against your file and found it after that i was able to upload it. Thanks Nikhil
omair_34
5 years ago
thanks
Amir Nickroo
5 years ago
Any suggestions on getting the image to fit inside the circle? Mine fille the entire screen? thx.
Brian Voong
5 years ago
Amir Nickroo
5 years ago
I tried that and I still get the same result. The image covers the entire phone. if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage { plusPhotoButton.setImage(editedImage.withRenderingMode(.alwaysOriginal), for: .normal) } else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage { plusPhotoButton.setImage(originalImage.withRenderingMode(.alwaysOriginal), for: .normal) } plusPhotoButton.layer.cornerRadius = plusPhotoButton.frame.width/2 plusPhotoButton.layer.masksToBounds = true plusPhotoButton.clipsToBounds = true plusPhotoButton.layer.borderColor = UIColor.black.cgColor plusPhotoButton.layer.borderWidth = 3 dismiss(animated: true, completion: nil)
Brian Voong
5 years ago
Amir Nickroo
5 years ago
I copy and pasted the source code for the photo icon in my viewdidload, didFinishPickingMediaWithInfo, and the handlePlusPhoto(), and it still did not work. It allows me to chose a photo and it loads it, but the size is too large. Any suggestions?
Brian Voong
5 years ago
Amir Nickroo
5 years ago
I got it! My extension UIVIew has a typo. Thank You
Brian Voong
5 years ago
Daryl Wong
5 years ago
I just encountered this same issuge where the image covers the entire phone. It was ok the last time I tried it.
PatrickVB
5 years ago
Your instructions are amazing. A huge key note is this *** These Instructions DO NOT Work in Xcode 9.1 *** Please build in Xcode 8.3.3. Xcode 9.1 has Many, Many Bugs! It took many many hours to figure this out! Thank You!
Brian Voong
5 years ago
Derik Malcolm
5 years ago
Hi Brian, when downloading the image from safari, it downloads as "profile_image.dms". I'm really confused on how to fix this.
nmfp
5 years ago
You just need to force the extension file you want on child's name like this: Storage.storage().reference().child("profile_images").child("\(filename).jpg").putData(uploadData, metadata: nil, completion: { (metadata, err) in...
swinful
5 years ago
Great suggestion. Thanks!
roi1672
5 years ago
Firebase might deny your permission so if anyone is having "permission denied" problem, go to your firebase console => storage => rules => and change the rules from allow read, write: if request.auth != null to allow read, write; And of course, remember to change it back when going production
rick27
5 years ago
Hello Brian, @ 3:31, line 105 you save the user into the database. I can successfully create the user but cannot save the user into the database. It seems that Firebase has changed the way they store these properties because now I cannot see any users in my realtime database tap. Last year I finished the course without any problem, but since the firebase update (2018) that includes the option for Cloud Firestore, I haven't been able to save any of my users to the database. Last years project works fine but any new project I make with the new Firebase, I run into this problem. I have tried making a new project, a new pod file, info.plist, opening the database tap before running the app, and even changing the permission rules. I've also read the current thread on this site and stackoverflow. I'm very interested in seeing what either I've missed or overlooked. Thanks in advance. -Rickey H.
rick27
5 years ago
Hey Brian, I did find the answer to my problem. For some odd reason my internet provider blocks some content. I simply had use another internet source. Thanks.
nombienombie
5 years ago
Hey Brain, We don't wire up any validation to ensure the user has selected a profile image, however if the don't, we can't save them to the db as the guard fails and we return early. How can we check if an image has been selected?
luoandre29
5 years ago
Keep a global boolean variable on top and when the imagePickerController finishes selecting an image then update the value to true. now we can check the boolean variable before attempting to save the image fileprivate var profileImageSelected:Bool = false func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage { plusPhotoButton.setImage(editedImage.withRenderingMode(.alwaysOriginal), for: .normal) profileImageSelected = true //updating value here } else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage { plusPhotoButton.setImage(originalImage.withRenderingMode(.alwaysOriginal), for: .normal) profileImageSelected = true //updating value here } // REST of code }
rehan1531
5 years ago
do I have to remember the Strings of info Dictionary like you did it info[UIImagePickerOriginalImage]? or is there any way to grab all these keys ?
Brian Voong
5 years ago
rehan1531
5 years ago
Thank you and its super amazing course , enjoying a lot :-)
rehan1531
5 years ago
Thank you and its super amazing course , enjoying a lot :-)
pdefilippi
5 years ago
Hey Brian, A little confused at the 2:48 mark. We set a ref in the completion handler. Is this 'ref' in regards to the Database.database().reference() ? I understand it to be in the completion block so is that what Firebase is returning once we set the values parameter?
Brian Voong
5 years ago
Sieder Villareal
5 years ago
so brian, whenever i upload an image for the plusPhotoButton, the editedImage is showing as well as the plus_photo image, images are stacking up, how do i get rig of this.
Sieder Villareal
5 years ago
nevermind brian, seems like i was using setbackgroundimage instead of setImage funtion.
shariar
5 years ago
Hi Brian! I have this error when I​ try to register and upload photo NSLocalizedDescription=An unknown error occurred, please check the server response., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=400}
Brian Voong
5 years ago
Smartopia
5 years ago
I had a same error. I logged out and log in again...but still same error! Any other solution for this?
Smartopia
5 years ago
I logged out and log in again..but same error! 2018-03-13 11:21:03.246055+0900 Smartopia Talk[31714:3693190] [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled} Failed to upload image Optional(Error Domain=FIRStorageErrorDomain Code=-13000 "An unknown error occurred, please check the server response." UserInfo={object=message_images/11D1EF26-6849-4284-8B63-C4563BB46B4D.jpg, bucket=smartopia-chat.appspot.com, ResponseBody={ "error": { "code": 400, "message": "Permission denied. Could not access bucket smartopia-chat.appspot.com. Please enable Firebase Storage for your bucket by visiting the Storage tab in the Firebase Console and ensure that you have sufficient permission to properly provision resources." } }, =An unknown error occurred, please check the server response., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=400})
Raph
5 years ago
I have the same problem, still can't find a solution... please let me know if you were able to get passed this, cheers!
Akiya Ozawa
5 years ago
Smartopia and Raph I hope you guys have already solved this problem. For those who are new to Firebase, you have to obtain permission to storage so I just did below to do it: 1, Go to Firebase console 2, Go to "Storage" section 3, A box shows up, telling about the rule of the storage 4, Click "OK" on the box. Hope this helps!
liupeng
5 years ago
Hi Brian! I save the username are found that the callback will not be executed code: Database.database (). reference (). child ("users"). child (uid) .setValue (["username": "alan"], withCompletionBlock: {(err, ref) in Print ("callback -------") // not execute }) xcode 9.2, firebase: 4.8.1 No error message my firebase database role rule are also open
liupeng
5 years ago
Using Firebase (4.8.2) Using FirebaseAnalytics (4.0.9) Using FirebaseAuth (4.4.2) Using FirebaseCore (4.0.14) Using FirebaseDatabase (4.1.4) Using FirebaseInstanceID (2.0.8) Using FirebaseStorage (2.1.2) Using GTMSessionFetcher (1.1.13) Using GoogleToolboxForMac (2.1.3) Using leveldb-library (1.20) Using nanopb (0.3.8)
liupeng
5 years ago
I created an empty project, test firebase database, but still no response, auth and storage module test ok. mycode: class ViewController: UIViewController { var ref: DatabaseReference! override func viewDidLoad() { super.viewDidLoad() setup() } private func setup() { self.ref = Database.database().reference() self.ref.child("users").child("sss").setValue(["username": "alan"]) { (err, ref) in print("hello") // not response } } }
Ashim Dahal
5 years ago
Hi brian, I have seen you using lazy var on the closure block whenever you are executing some additional runtime​ function as addTarget or gestureRecoginzer or any other event handler. I didn't see you doing this on for addPhotoHandler. Anything that I am missing here? Could you elaborate? I had studied on Lazy loading. Which refers to as if there are completion block that the variable is waiting we are assigning it as Lazy as initialization for the variable is yet to be determined. i.e We are waiting for some event to happen before the variable is completely initialized properly. The reason you have to write objc function is because swift is not a dynamic program. All the initialization happen at compile time as compared to objective c where initilization can happen at run time.
Brian Voong
5 years ago
fabien040
5 years ago
Hi Brian and friends, I was using createUser and I was getting Error Domain=FIRAuthErrorDomain Code=17007... It seems that it has changed to Auth()auth.signIn(withEmail:... note: I did Pod update and several Firebase packages updated too
fabien040
5 years ago
my mistake
omari
5 years ago
Hello Brian, what happens if you have one million user and one specific user tries to login -> This means that your tree has one million entries. So how long does it take to find this specific user and give him access. Is this the right way of designing this tree structure. What are possible obstacles ?
Brian Voong
5 years ago
DerekRM
5 years ago
This might be a stupid and basic question because I can't find it on google. I got a new mac after completing Ep 3. Do I need to install cocoa pods onto this computer. and if so how does that work with the xcode files i transferred over from my old computer.
DerekRM
5 years ago
It was a stupid question
ttmart3
5 years ago
Hi Brian, Great video, I am stuck on one thing right now. On Xcode it is saying this "Use of unresolved identifier 'user' guard let uid = user?.uid else { return } let values = [uid: 1] Database.database().reference().child("Users").setValue(values) { (err, ref) in if let err = err { print("Failed to save user in Database:", err) } print("Successfully saved user to database!") } }
Brian Voong
5 years ago
ttmart3
5 years ago
Hi Brian, Thank you! I was looking in the wrong spot in the code. Great work!
firdausizrullah
5 years ago
Hi brian, I have reached the user photo access stage, but in the video tutorial you show that access the user's photo before adding the settings in info.plist an error occurs. at the time i try not to get error and can access the user photo ... but when i add setting in info.plist do not show any questions as there is in video tutorial ... should i keep add the setting or it's default from swift ?
Brian Voong
5 years ago
firdausizrullah
5 years ago
Thanks for your response brian, i've been testing in my device (iphone x), it also same with the simulator .. the dialogues didn't show up .. :(
dshawn
5 years ago
Hey Brian, I had a quick question. Should I use Firestore or realtime database? Also the realtime database says "Default security rules require users to be authenticated", how do I go about doing that?
Brian Voong
5 years ago
dshawn
5 years ago
Ok thank you! that helps a lot. Also I have an app that I am hopefully going to release for beta testing Sunday! I'd love if you'd test it out and let me know what you think. (If you'd like to test it, send me an email: dshawnastewart@gmail.com)
Anirudh Bandi
5 years ago
while selecting images from pickerview the else condition handling the original image is almost never executed. If i want to use the original image without editing how can i do that?
Brian Voong
5 years ago
Anirudh Bandi
5 years ago
Thanks for such a quick reply. I should have been clear. what I want is to give the user the option to either use the original image or the edited one. How should I go about doing this?
Guylain Malanda
5 years ago
Hey Brian! Thank you for this awesome course... When I go further, I have these alert messages and I can't run the app!! In the UserProfileHeader: Value of type 'User' has no member 'username' Value of type 'User' has no member 'profileImageUrl' In the UserProfileController: Cannot assign value of type 'UserProfileController.User?' to type 'User?' What can I do ?
Gabriel Seben
5 years ago
Hi Bryan, I tried uploading the image and got a new rule Firebase is requesting a security rule addition You are returning an error of this type uploading the image ResponseBody={ "error": { "code": 400, "message": "Permission denied. Could not access bucket clinicapefirebase.appspot.com. Please enable Firebase Storage for your bucket by visiting the Storage tab in the Firebase Console and ensure that you have sufficient permission to properly provision resources." } } Firebase is requesting to add this piece of code service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write: if request.auth != null; } } }
Brian Voong
5 years ago
AlfieLBTA
5 years ago
where do i put that piece of code ?
AlfieLBTA
5 years ago
I respond for myself and other developers with the same question : The code its added automatically once you hit continue "lets get stared" , the code is pasted on the rules tab
AlfieLBTA
5 years ago
how did u manage to upload it i got this message : User does not have permission to access gs://instagramfirebase-5a916.appspot.com/ even tough i have storage permission set like this service firebase.storage { match /b/{bucket}/o { match /{allPaths=**} { allow read, write; } } }
darren100
5 years ago
metaData.downloadURL() no longer usable. I tried everything even creating my own closure but still can't get the URL. help pls.
darren100
5 years ago
wtf, so it still works. I hate when swift show a red crossed out line and give me a warning: "'downloadURL()' is deprecated: Use `StorageReference.downloadURLWithCompletion()` to obtain a current download URL" wasted 2 hours using that call. -.-
xavierliancw
5 years ago
So a few things: - Google deprecated the .downloadURL() method, so we shouldn't use it anymore because they'll get rid of it in a future update - It's a nice thing that Xcode recognizes when things are deprecated - To get the url now: - - Look in the metadata for .storageReference - - Do metadata?.storageReference.downloadURL with completion block - - You'll get a URL? and an Error? parameter - - If the url isn't nil, that's your download url - So yeah, you have to make another async call within an async call
xavierliancw
5 years ago
Hmm... I take back what I said about getting the download URL because it's not working for me. I'll get back to you.
xavierliancw
5 years ago
Got it. You have to do: Storage.storage().reference().child("profile_pics").child(YOUR_PHOTO_NAME).downloadURL(completion: { (possURL, possErr) in if let url = possURL { //url.absoluteString is your photo url :D } })
Brian Voong
5 years ago
pawelcichonski
5 years ago
Two things: 1) This is the new syntax (but it lacks putData for the uploadData) Storage.storage().reference().child("profile_image").downloadURL(completion: { (metadata, err) in if let err = err { print("Failed to upload profile image: ", err) return // return if it fails } guard let profileImageUrl = metadata?.absoluteString else { return } print("Sucessfully uploaded profile image", profileImageUrl) }) ... 2) But then again the uploadData is unused, don't know where to putData now as the syntax changed: guard let uploadData = UIImageJPEGRepresentation(image, 0.3) else { return } // NOT USED Any help would be appreciated Brian. Thank you
pawelcichonski
5 years ago
Ignore the previous one. Think I just solved that one. Here is the updated version of the code (below screenshots of firebase upload) 1) https://i.imgur.com/0JdxrxE.jpg 2) https://i.imgur.com/mk0B1v5.jpg ////////////////////////////// guard let image = self.addProfilePhoto.imageView?.image else { return } guard let uploadData = UIImageJPEGRepresentation(image, 0.3) else { return } Storage.storage().reference().child("profile_image").putData(uploadData, metadata: nil, completion: { (metadata, err) in if let err = err { print("Failed to upload profile image: ", err) return // return if it fails } Storage.storage().reference().child("profile_image").downloadURL(completion: { (url, error) in guard let profileImageUrl = url?.absoluteString else { return } print("Sucessfully uploaded profile image", profileImageUrl) }) }) //////////////////////////////
xavierliancw
5 years ago
Why don't we name profile pictures with a user's uid instead of a random UUID string? Wouldn't this make it easier to replace profile pictures in the future?
AlfieLBTA
5 years ago
For those having issues with the FireBase permissions heres the actual code as off May 17th 2018 with Swift 4 and Xcode 9.1 guard let profileImage = self.addPhotoBtn.imageView?.image else { return } guard let uploadData = UIImageJPEGRepresentation(profileImage, 0.5) else { return } let storageRef = Storage.storage().reference() let storageRefChild = storageRef.child("user_profile_pictures/\(uid).jpg") storageRefChild.putData(uploadData, metadata: nil, completion: { (metadata, err) in if let err = err { print("Unable to upload image into storage due to: \(err)") } storageRefChild.downloadURL(completion: { (url, err) in if let err = err { print("Unable to retrieve URL due to error: \(err.localizedDescription)") return } let profilePicUrl = url?.absoluteString print("Profile Image successfully uploaded into storage with url: \(profilePicUrl ?? "" )") }) }) You must ask the Url from the Child node and not the storageBin , took me a while to realize that =) , so happy now i can move forward.
Hesh Rukunayake
5 years ago
Thanks, i was stuck for ages on this section
sheyi64
5 years ago
Thanks a bunch Bro... Whats stuck here for ages... Your code was a Life Saver... Thumbs Up... Now i can move on...
Pren22
5 years ago
Hey Brian, I am currently working on this project piece! when selecting the image from the image picker it comes back well with the selected photo but the picture come back with this black bar on the right side of the photo, almost like it is being clipped and the image is not completely setting itself in the circle properly. If anyone happens to know why that is please give me a hand!
Brian Voong
5 years ago
sashensingh
5 years ago
Hey Brian, great videos i'm really learning a lot, just a quick question with the new firebase updates i have to use .downloadURL for the storage reference to obtain the downloadUrl seems like this is no longer associated with the metaData, .downloadURL has a completion block and therefore on success of that(no error returned) then do i only save the user to the database else the downloadURL will be empty if i don't put it in this completion, my question is..is this good practise? I feel like my code is nesting somewhat within all these completions
antoniy999
5 years ago
Hey Brian, I have one question and i don't know how to solve it 'UIImageJPEGRepresentation' has been replaced by instance method 'UIImage.jpegData(compressionQuality:)' https://imgur.com/a/D95WCoY
Brian Voong
5 years ago
p31d3ng
5 years ago
Hey Brian, I got a question: for the createUser completion closure, do we need a `[unowned/weak self]` to get access to self.plusPhotoButton? There could a strong ref cycle here: ViewController obj -> FIRAuth, the completion closure which belongs to FIRAuth -> handlePlusPhoto().
p31d3ng
5 years ago
Sorry one typo. The ref cycle should be handlePlusPhoto() -> FIRAuth, the completion closure which belongs to FIRAuth -> handlePlusPhoto()
p31d3ng
5 years ago
oh..i mistype the function name completely!!! OK, let me rephrase my question: step 1. handleSignUp() contains FIRAuth.auth().createUser(), which will create a ref from handleSignUp() -> FIRAuth step 2. FIRAuth.auth().createUser() has a closure, which will modify self.plusPhotoBtn.imageView?.image, and therefore create a ref from FIRAuth -> self (which is ViewController). step 3. handleSignUp() is a function of ViewController. (I could be wrong here, instance method sits on text segment which could not init any instance.. but that's what i'm confused) therefore, there's a strong ref cycle: FIRAuth <-> ViewController. Do we need a [unowned/weak self] to break this strong ref cycle?
RichyCode
5 years ago
this is the full signup code for swift 4.2 as of 9/07/2018 ------------------------------------------------------- { guard let email = emailTextField.text, !email.isEmpty else {return} guard let username = usernameTextField.text, !username.isEmpty else {return} guard let password = passwordTextField.text, !password.isEmpty else {return} Auth.auth().createUser(withEmail: email, password: password) { (user: User?, error: Error?) in if let err = error { print("failed to create user", err) return } print("success...created a user in firebase") //upload photo guard let image = self.plusButtonPhoto.imageView?.image else {return} guard let uploadData = UIImageJPEGRepresentation(image, 0.3) else {return} let filename = NSUUID().uuidString //firebase storage let storageRef = Storage.storage().reference() let storageRefChild = storageRef.child("profile_images").child(filename) storageRefChild.putData(uploadData, metadata: nil, completion: { (metadata, err) in if let err = err { print("Unable to upload image into storage due to: \(err)") } storageRefChild.downloadURL(completion: { (url, err) in if let err = err { print("Unable to retrieve URL due to error: \(err.localizedDescription)") return } let profilePicUrl = url?.absoluteString print("Profile Image successfully uploaded into storage with url: \(profilePicUrl ?? "" )") //--firebase storage end guard let uid = user?.uid else {return} let dictionaryValues = ["username": username, "profilePicUrl": profilePicUrl] let values = [uid: dictionaryValues] Database.database().reference().child("users").updateChildValues(values, withCompletionBlock: { (err, ref) in if let err = err { print("failed to save user info", err) return } print("sucessfully saved user info to db") }) }) }) } }
Patrick Cockrill
5 years ago
We still get the error with "Value of type 'AuthDataResult' had no member 'uid'"
RichyCode
5 years ago
Works for me mate
dclawson
5 years ago
Dumb question: you're using the "Auth" and "Database" classes, and mine defaulted to "FIRAuth" and "FIRDatabase". Has the interface changed in the past month?
dclawson
5 years ago
I also copy-pasted all of the "ViewController.swift" file from the download put it in my project. I get the error: Value of type 'FIRUser' has no member 'user' Trying to look through the documentation now.
dclawson
5 years ago
Sorry to spam the channel again, but I think the code went from: guard let uid = user?.user.uid else { return } to: guard let uid = user?.uid else { return } Now I can get the email address to register, and the photo to upload, but this error keeps coming up: Failed to save user info into db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied} 2018-07-17 18:24:04.581168-0600 InstagramFirebase[38618:1747832] [Firebase/Database][I-RDB03812] updateChildValues: at /users failed: permission_denied
pawelcichonski
5 years ago
dclawson You got your error not because of your code but because of your permissions on firebase. Go to Firebase: Database / Rules and change the values to true: { /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */ "rules": { ".read": true, ".write": true } } Also, in Xcode swift, the correct code is: "guard let uid = user?.user.uid else { return }" Checked today and is all successful
rickkettner
5 years ago
The line should be: guard let uid = authResult?.user.uid else { return }
Santa
5 years ago
thanks!
dclawson
5 years ago
I'm getting an error: "setValue: or removeValue: at /users failed: permission_denied". I can get the user created, no problem, but it won't let me write to the DB. I've even changed the permissions to be wide open. I'm logged in on my laptop. I created a "users" collection in the "Database" section, and manually added an entry and then tried it again. Any ideas?
RichyCode
5 years ago
I think firebase was having issues yesterday could have been related
dclawson
5 years ago
I just figured this out. I was somehow connected with the Cloud Firestore BETA. I changed it back to the traditional interface, and changed the permissions to open, and then re-saved and it worked. Makes me wonder how/if I should go back to the beta and eventually figure out how it works.
tatters
5 years ago
I had the same issue. I think Firebase defaults to the Beta version on creation of a new project. I changed it to the original and then set the read and write rules to true....and it worked. Brian's updates on the down load file where updated for handleSignUp()...everything was the same as the original video tutorial.
arian
5 years ago
@brianvoong Hi Brain,Do you have any idea why I'm getting Successfully created and saved user info in db inn XCODE debugger, but the data is not showing saved in Firebase Database.!!
arian
5 years ago
I figured it out, i needed to update the "rules" to be: { "rules": { ".read": true, ".write": true } } and save it by tapping "publish"
arian
5 years ago
@brian Hi Brian i think you need to update the code for the profileimageURl as "downloadURL()" is deprecated so the code to get the downloadedImageURL should be: Storage.storage().reference().child(“profile_image”).downloadURL(completion: { (url, error) in if let err = error { print(“failed to get the download link”,err) return } else { guard let profileImageURL = url?.absoluteString else {return} print(“Successfully uploaded profile image”, profileImageURL)
azhar
4 years ago
How do you save the url outside of the closure body?
Duc Vu
5 years ago
This is my version of the handleSignUp() method: @objc func handleSignUp() { let email = emailTextField.text let password = passwordTextField.text Firebase.Auth.auth().createUser(withEmail: email!, password: password!) { (user: AuthDataResult?, error) in if let err = error { print("Failed to create users: ", err) } else { print("Successfully create user") guard let userid = user?.user.uid else { return } let username = self.usernameTextField.text! let usernameValue = ["username":username] let value = [userid: usernameValue] Firebase.Database.database().reference().child("users") .updateChildValues(value, withCompletionBlock: { (error, ref) in if let err = error { print("Failed to save user info: ", err) } else { print("Successfully saved user info") } }) } } }
Hamzah
5 years ago
Hey Brian! my code says: guard let uid = user?.uid else {return} and i even tried: guard let uid = user?.user.uid else {return} but it does not work. The error msg says use of unresolved identifier "user" Can someone pls help, Thanks!
Brian Voong
5 years ago
jamal.nasir
5 years ago
minor changed from Duc Vu code: @objc func handleSignUp() { let email = emailTextField.text let password = passwordTextField.text Auth.auth().createUser(withEmail: email!, password: password!) { (user, error) in if let err = error { print("Failed to create users: ", err) } else { print("Successfully create user") guard let userid = user?.uid else { return } let username = self.usernameTextField.text! let usernameValue = ["username":username] let value = [userid: usernameValue] Firebase.Database.database().reference().child("users") .updateChildValues(value, withCompletionBlock: { (error, ref) in if let err = error { print("Failed to save user info: ", err) } else { print("Successfully saved user info") } }) } } }
hudsonpereira
5 years ago
Hey, good jog there. Minor feedback: instead of using else on if statements you can return from it. Then everything that comes after the if is the else. No need to indent there.
akidwai
5 years ago
Is anyone having issues where the image does not set to the plusPhotoButton after editing and choosing the image?
Brian Voong
5 years ago
akidwai
5 years ago
The downloaded sample works. I fixed my issue, it was a build setting issue on my part. Thank you for your response!
rickkettner
5 years ago
FYI, don't need to use a string/quotation-marks for: info[UIImagePickerControllerOriginalImage] It's possible to remove the quotation marks, which reduces the risk of typos by having the text validated by the Xcode auto complete.
rickkettner
5 years ago
Also, I believe if you have editing enabled, then the return image is "edited" no matter what... so the "else if" for original image becomes unnecessary. Even if unzoomed, the image coming back will always be "edited", or at least that is my understanding.
Brian Voong
5 years ago
rickkettner
5 years ago
Ahh, makes sense!
Brian Voong
5 years ago
hudsonpereira
5 years ago
Thanks for this info!
rickkettner
5 years ago
I'm able to successfully upload a profile image, but when I go to view it my browser isn't able to preview it. And when I download it my computer doesn't seem to know what to do with it by default... until I append ".jpg" on it. Should I be appending ".jpg" on the filename in code?
Brian Voong
5 years ago
rickkettner
5 years ago
Nevermind, I'm able to view it without file extension.
rickkettner
5 years ago
I sorted it. Thank you for your help! Enjoying the course so far.
Chance Robertson
5 years ago
Does anybody have the full and final updated code for the handleSignUp function that includes the profileImageURL code as well?
hudsonpereira
5 years ago
I do
ted.liu
5 years ago
Hi Brain,the latest source code have a bug . in AppDelegate.swift file line 18:UIApplication.LaunchOptionsKey should be UIApplicationLaunchOptionsKey,please fix it.
Brian Voong
5 years ago
ted.liu
5 years ago
Hi Brain,I am user xcode 9.4.1 let dictionaryValues = ["userName":"myname", "profileImageUrl":"http://xxx.jpg"] let values = ["0001" : dictionaryValues] Database.database().reference().child("users").setValue(values, withCompletionBlock: { (err, ref) in if let err = err { print("Failed to update user info to db", err) return } print("Successfully update user info to db") }) this test code doesn't excute withCompletionBlock,did I do something wrong?
ted.liu
5 years ago
Analyzing dependencies Downloading dependencies Using Firebase (5.7.0) Using FirebaseAnalytics (5.1.1) Using FirebaseAuth (5.0.3) Using FirebaseAuthInterop (1.0.0) Using FirebaseCore (5.1.2) Using FirebaseDatabase (5.0.2) Using FirebaseInstanceID (3.2.1) Using FirebaseStorage (3.0.1) Using GTMSessionFetcher (1.2.0) Using GoogleAppMeasurement (5.1.1) Using GoogleUtilities (5.2.3) Using leveldb-library (1.20) Using nanopb (0.3.8) Generating Pods project Integrating client project Sending stats
Brian Voong
5 years ago
seventhaxis
5 years ago
I don't understand why I cannot upload a picture to FB storage. After declaring storageRef, it seems to execute the following line but doesn't enter the closure. See code below: ##################### guard let avatar = self?.addPhotoButton.imageView?.image else { return } guard let compressedImage = UIImageJPEGRepresentation(avatar, 0.3) else { return } let storageRef = Storage.storage().reference().child("profile_images").child(user.uid).child(imageFileName) storageRef.putData(compressedImage, metadata: nil, completion: { ... })
seventhaxis
5 years ago
As a follow up to my own comment, Brian helped me discover that I was missing the pod 'Firebase/Core' within my Podfile. It's not mentioned in the video but he's working on an update. It will likely resolve issues others are experiencing as well with Xcode barking about Analytics. If anyone else experiences this or a similar issue, edit your Podfile to include 'Firebase/Core' and then do a pod install; you should be good after.
nitpa7
5 years ago
Hey guys, does anyone get the error below in the handle sign up function while updating data into the database. Successfully created a user: c8kNyQz0WnhQhv3f40FqUs9MG6U2 Failed to save user info into DB Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied} I'm able to create user successfully but unable to update into the database. below is the handle sign up function swift 4.2 code. @objc func handleSignUp() { guard let email = emailTextField.text, email.count > 0 else { return } guard let username = usernameTextField.text, username.count > 0 else { return } guard let password = passwordTextField.text, password.count > 0 else { return } Auth.auth().createUser(withEmail: email, password: password) { (authDate, error) in if let err = error { print("Failed to create user:", err) return } print("Successfully created a user:", authDate?.user.uid ?? "") guard let uid = authDate?.user.uid else { return } let usernameValues = ["username" : username] let values = [uid : usernameValues] Database.database().reference().child("users").updateChildValues(values, withCompletionBlock: { (err, ref) in if let err = err { print("Failed to save user info into DB", err) return } print("Successufully saved user info into DB") }) } }
seventhaxis
5 years ago
You need to go into your Firebase console and set your database rules to be public. See example below: { "rules": { ".read": true, ".write": true } }
nitpa7
5 years ago
these are my current ( default ) rules.. service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } } } and I am unable to edit them..
Brian Voong
5 years ago
beto123
4 years ago
you are on the cloud.firebase not the realtime database. Make sure you are in the right place. there should be a tab where you can switch between the two. I was having the same problem. those are the permissions from the cloud.
teisaacs21w
4 years ago
Firebase has two types of databases, Cloud Firestore and Realtime Database. The configuration you have is for Cloud Firestore (service cloud.firestore ...). At the top of the Firebase console switch to the Realtime Database and change your security to allow read and write. { "rules": { ".read": true, ".write": true } }
nitpa7
4 years ago
thank you so much beto123.
startingpoint
4 years ago
Make sure you toggle to 'Realtime database', not the default 'Cloud firestore' https://i.imgur.com/TlY0r68.png
Christian O. Vargas
4 years ago
Life saver!
gurminder290195
4 years ago
hey brain, imagePickerController is not working is anything changed in xcode update. can you please fix it
Chuan Lai
4 years ago
UIImageJPEGRepresentation could'nt use
Brian Voong
4 years ago
Goldor
4 years ago
Quick answer: guard let profileImage = self.plusPhotoButton.imageView?.image else {return} let uploadData = profileImage.jpegData(compressionQuality: 0.3)
Chuan Lai
4 years ago
storage error message Failed to fetch downloadURL: Error Domain=FIRStorageErrorDomain Code=-13021 "User does not have permission to access gs://igplactice.appspot.com/(null)." UserInfo={bucket=igplactice.appspot.com, ResponseBody={ "error": { "code": 403, "message": "Developer credentials required." } }, data_content_type=application/json; charset=UTF-8, data=<7b0a2020 22657272 6f72223a 207b0a20 20202022 636f6465 223a2034 30332c0a 20202020 226d6573 73616765 223a2022 44657665 6c6f7065 72206372 6564656e 7469616c 73207265 71756972 65642e22 0a20207d 0a7d>, NSLocalizedDescription=User does not have permission to access gs://igplactice.appspot.com/(null)., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=403} how to fix it?
Chuan Lai
4 years ago
i think im rite
Chuan Lai
4 years ago
can i discuss with u im taiwaness
Brian Voong
4 years ago
Chuan Lai
4 years ago
Auth.auth() 這行我跑得過喔 @objc func handleSignUp(){ guard let email = emailTextField.text else{return} guard let password = passwordTextfield.text else{return} guard let name = nameTextField.text else{return} Auth.auth().createUser(withEmail: email, password: password) { (result: AuthDataResult?, error: Error?) in if let err = error{ print("fail to create user",err) return } print("successfully to create user",result ?? " ") // guard let image = self.plusButton.imageView?.image else {return} // guard let uploadData = image.jpegData(compressionQuality: 0.3) else { return } //UIImageJpegRepresentation不能用了 guard let uploadData = self.plusButton.imageView?.image?.jpegData(compressionQuality: 0.3) else{return} let fileName = NSUUID().uuidString Storage.storage().reference().child("profile_image").child(fileName).putData(uploadData, metadata: nil, completion: { (metaData: StorageMetadata?,err: Error?) in if let err = err { print("fail to up load profile image",err) return } // Firebase 5 Update: Must now retrieve downloadURL Storage.storage().reference().downloadURL(completion: { (downloadURL: URL?,err: Error?) in if let err = err{ print("Failed to fetch downloadURL:", err) return } guard let profileImageUrl = downloadURL?.absoluteString else { return } print("Successfully uploaded profile image:", profileImageUrl) guard let uid = result?.user.uid else {return} let userValues = ["userName:":name] let values = [uid:userValues] Database.database().reference().child("user").updateChildValues(values, withCompletionBlock: { (err: Error?,databaseref:DatabaseReference ) in if let err = err { print("Fail to save user info into db",err) return } print("Successfully to save user info into db") }) }) }) } }
Chuan Lai
4 years ago
print("successfully to create user",result ?? " ") 這裡我通過了 但是錯誤出在 Storage.storage().reference().downloadURL(completion: { (downloadURL: URL?,err: Error?) in if let err = err{ print("Failed to fetch downloadURL:", err) return } 網路上說要修改FIREBASE的RULE 我怎樣修改都失敗 錯誤訊息是 successfully to create user <FIRAuthDataResult: 0x6000038c6220> Failed to fetch downloadURL: Error Domain=FIRStorageErrorDomain Code=-13021 "User does not have permission to access gs://igplactice.appspot.com/(null)." UserInfo={bucket=igplactice.appspot.com, ResponseBody={ "error": { "code": 403, "message": "Developer credentials required." } }, data_content_type=application/json; charset=UTF-8, data=<7b0a2020 22657272 6f72223a 207b0a20 20202022 636f6465 223a2034 30332c0a 20202020 226d6573 73616765 223a2022 44657665 6c6f7065 72206372 6564656e 7469616c 73207265 71756972 65642e22 0a20207d 0a7d>, NSLocalizedDescription=User does not have permission to access gs://igplactice.appspot.com/(null)., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=403}
Chuan Lai
4 years ago
好像是FIREBASE的安全性問題 現在都要修改STORAGE的RULE(不是DATABASE)
Brian Voong
4 years ago
Chuan Lai
4 years ago
寄給您了謝謝老師
Chuan Lai
4 years ago
match /b/instagramdemo-c7897.appspot.com/o 這個bucket裡面要放時麼?
Chuan Lai
4 years ago
service firebase.storage { match /b/igplactice.appspot.com/o { match /{allPaths=**} { allow read, write; } } } 這是我的 出錯了
Chuan Lai
4 years ago
and the second question: ive try to get uid of fb how do i fetch downloadurl and sotre frofilepicture inti firebase?? the following is mycode func handleFBSignup() { // let accessToken = FBSDKAccessToken.current() // guard let accessTokenString = accessToken?.tokenString else {return} // let credentials = FacebookAuthProvider.credential(withAccessToken: accessTokenString) let credentials = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString) Auth.auth().signInAndRetrieveData(with: credentials) { (result: AuthDataResult?, err: Error?) in if let error = err{ print("Something went wrong with our fb user",error ) } print("successfully to log in fb user",result ?? "") guard let fbName = result?.user.displayName else {return} guard let uid = result?.user.uid else {return} let userValues = ["userName:":fbName] let values = [uid:userValues] Database.database().reference().child("user").updateChildValues(values, withCompletionBlock: { (err: Error?,databaseref:DatabaseReference ) in if let err = err { print("Fail to save user info into db",err) return } print("Successfully to save user info into db") }) } FBSDKGraphRequest(graphPath: "/me", parameters: ["fields":"id,name,email"])?.start(completionHandler: { (connection: FBSDKGraphRequestConnection?, result: Any?, error: Error?) in if error != nil{ print("Fail to start graph request",error ?? " ") return } print(result ?? " ") }) }
morrison
4 years ago
Hi Brian, In my putData function, the completion handler is never called though. Have you ever got that issue? I already tried pod deintegrate, pod clean then installed the 4 Firebase SDK as you mentioned but it still doesn't work.
morrison
4 years ago
It could save the profile_image to Storage on Firebase but because the completion handler wasn't called, it couldn't save new user to Database. Instead I got these messages: [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C3.1:2][0x7fe8d3428000] get output frames failed, state 8196
Brian Voong
4 years ago
shawnbierman
4 years ago
I'm having the same problem. What was the solution for this?
Brian Voong
4 years ago
shawnbierman
4 years ago
Thanks. I actually already had that in there along with the other files mentioned in the caption under lesson three. I'm just going to start over, it's a reinforcement opportunity. I have a hunch about the problem.
Brian Voong
4 years ago
Chuan Lai
4 years ago
我看到了,但為何要建立一個ref做存取呢???
Uaa
4 years ago
Hi Brain,i have err in xcode 10: <Value of type 'StorageMetadata' has no member 'downloadURL'> guard let profileImageUrl = metadata?.downloadURL()?.absoluteString else { return }
Brian Voong
4 years ago
Robby
4 years ago
Hi Brain, I don't know if this is a bug on my app or maybe Swift 4 handles this different from the previous versions but in my app, the alert message is not showing when user push the plusPhotoButtom to access the images! Is this something that I want to use in the app. The rest of the code works perfectly, you are the best!
Brian Voong
4 years ago
Patrizio
4 years ago
Hi Brain, I have a problem with the image assignment to the plusPhotoButton. I receive correctly the images form the ImagePickerController, but when I call the setImage button's method, the button grows to the size of the image instead of the image shrink to the size of the button. I can't find the property to set to change this behavior. Any ideas?
Brian Voong
4 years ago
Patrizio
4 years ago
Your code is fine, I will post back when I realize where is the problem. Thanks.
Patrizio
4 years ago
I found my error. I forgot to set the isActive property for the height and width constraint in the view extension. My bad. :(
amukasa
4 years ago
Hey Brian, I have followed your instructions according to the new firebase code update. I'm getting a build error saying "Value of type 'User' has no member 'user' " at print statement for creating a new user. Do you know why this is happening? I'm guessing it has something to do with firebase.
amukasa
4 years ago
Here's a snippet of the code: I get the build error at the print statement Auth.auth().createUser(withEmail: email, password: password, completion: { (user, error: Error?) in if let err = error { print("Failed to create user:", err) return } guard let image = self.plusPhotoButton.imageView?.image else { return } guard let uploadData = image.jpegData(compressionQuality: 0.3) else { return } let filename = NSUUID().uuidString let storageRef = Storage.storage().reference().child("profile_images").child(filename) storageRef.putData(uploadData, metadata: nil, completion: { (metadata, err) in if let err = err { print("Failed to upload profile image:", err) return } print("Successfully created user:", user?.user.uid ?? "")
esong2288
4 years ago
Do we still need to upload images into Firebase storage considering that .putData and .downloadUrl are now separate functions? I might be misunderstanding this, but it seems to me that the images are being extracted using a download url in the database and not in storage, so is there a point for me to fill up my storage?
Brian Voong
4 years ago
Vinney
4 years ago
Hi, Brian I've tried that out but there is still some problem I'm able to store the profile images to Firebase Storage However, the profile image block is not working I have set the breakpoints to debug but the problem remains the same. https://pastebin.com/XpWTRnvV I've pasted the code block into paste bin It would be great if you can help me out with this. Thanks Buggy
Brian Voong
4 years ago
Vinney
4 years ago
Thanks Brian I just updated my pods and everything is working smoothly.
Vinney
4 years ago
Hi, Brian Voong first of all thanks for proving such an amazing content, I was working on this app since Firebase has made changes to storage the downloadUrl property is not accessible anymore, I check their documentation and what I found doesn't seem to work. Although, there are no syntax error but it is not working referance.downloadURL(completion: { (url, err) in if let error = err{ print("Error uploading the file ",error.localizedDescription) } if let url = url{ print("The image has been saved with the url of ", url.absoluteString) } print("Not sure what happened here") }) }) The image is saving to firebase database but I can't access to url location which means can't store in database.
Brian Voong
4 years ago
diegoseb
4 years ago
Hi Brian, Does the 'allowEditing' property let change both the proportion of the crop zone* and the output size of the jpg**? * by default it only allows to crop the image into a 1:1 zone, can this be set like 1:2 or other desired ratios? ** by default it exports the jpg with a stablished width (750px), can this setting be modified? Thank you :)
Brian Voong
4 years ago
Huseyint945@gmail.com
4 years ago
hey Brian, I coppie your handleSignup method from projectCode, but profile image url is not being updated. when I check the log the last thing it does is printer profileimageurl. after that nothing. can you help me out
dale
4 years ago
Hi Brian, somehow the image that I picked from my photo library does not show up on the plus photo button. I copied your code exactly. Thanks!
Ayub9992
4 years ago
Hi Brian. I am doing this part where I need to downloadURL method. I figured it out the code need except every time I use downloadURL I get this permissions error from firebase storage. Saying user does have permission with the error Code=-13021. I looked on stacksoverflow and other coding blogs they said that I had to adjust the permissions in firebase storage. I did that and waited one minute to allow firebase to reconfigure however that didn't help at all. I am still getting the error which is preventing the username and the user profile image from being saved into the firebase db. How do I get around this problem. Thank you
Brian Voong
4 years ago
Ayub9992
4 years ago
Okay by properly do you mean like when I create the new user through the signup screen. I should see the new user in the firebase auth side. Where the new users populate. If so I already have that down. Umm. I compared my code to the resource that you provided. Even without the resource help I seem to get the code right with some trouble shooting. However I am still getting the permissions error from the firebase. I think it is the why that I have permissions configured. I have checked it however everything for some reason looks in order. I have contacted google about this. Hopefully they have an answer for me.
Brian Voong
4 years ago
Ayub9992
4 years ago
Yup figured it out. I was calling this incorrectly let storageRef = Storage.storage().reference().child I had it the way firebase doc had it. I had storageRef= Storage.storage().reference() Then on other code I was calling it in a chain. And I think just having multiple calls of it was messing it up. I stuck to one call at the very beginning and the code run fine. Now I don't get permission error and uploaded user data to the database. Thanks for your help.
MaxApp
4 years ago
Hey Brian, I am working on saving the user info to DB but I it keeps failing since the database is never created. When I went to the firebase -> database. I was able to create a new database but not really sure if I should set the Security rules for Cloud Firestore. There are two choices 1. Start in locked mode 2. Start in test mode
Brian Voong
4 years ago
ncytimothy
4 years ago
Locked Mode is the mode restricting all third-party reads and writes. The default Rules for the Realtime DB: Locked Mode: // These rules don't allow anyone read or write access to your database { "rules": { ".read": false, ".write": false } } If you would like to get some help, @mutaeb, I can help with writing a post here and at the top so that people can catch what they need to do. To make it work: 1) Use Test Mode (essentially all third parties are allowed to freely read and write (keep using Brian's code), or 2) Setting the "User" DB rules, but modify your Database.database.reference() call a bit: Rules: (https://firebase.google.com/docs/database/security/quickstart) // These rules grant access to a node matching the authenticated // user's ID from the Firebase auth token { "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } } Database.database.reference() call: Note the extra "child(uid)" assessor after "child("users"), congruent with the rules nodes that are set up. Database.database().reference().child("users").child(uid).setValue(values, withCompletionBlock: { (error, ref) in if let error = error { debugPrint("Failed to save user info into db: \(error)") return } print("Successfully saved user info to db")
MaxApp
4 years ago
Brian, I have been having an issue and I was not able to solve it even after the research I did I tried this but it won't work var profileImageURL = "" metadata?.storageReference?.downloadURL(completion: { (url, error) in if let err = error { print("Failed to save profile image URL:", err) return } profileImageURL = url }) I'm trying to get the url of the Image thanks
Brian Voong
4 years ago
MaxApp
4 years ago
Oh, thanks I never knew that you update the source code.
ncytimothy
4 years ago
For whoever's experiencing the "permissions error", this is likely due to your Rules that are set up in Realtime DB. In your console, click on Realtime Database, go ahead and create one if you haven't already and: 1) Use Test Mode (all third parties are allowed to freely read and write (keep using Brian's code), or 2) Setting the "User" DB rules, but modify your Database.database.reference() call a bit: "User" Rules: (https://firebase.google.com/docs/database/security/quickstart) // These rules grant access to a node matching the authenticated // user's ID from the Firebase auth token { "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } } Database.database.reference() call: Note the extra "child(uid)" assessor after "child("users"), congruent with the rules nodes that are set up. Database.database().reference().child("users").child(uid).setValue(values, withCompletionBlock: { (error, ref) in if let error = error { debugPrint("Failed to save user info into db: \(error)") return } print("Successfully saved user info to db")
arpethel
4 years ago
ncytimothy, I'm actually trying to implement these rules, but I'm hung up on a few things. First, your `.setValue` method is different than the one used, `.updateChildValues`. Is there a reason for that? Secondly, I'm not sure how to place the rules in the Database Rules tab. I've just placed the code you provided (the same as in the link you've provided) in my Rules tab (all curly braces match up), but I'm getting a few errors: 1) Missing 'match' keyword before path. 2) mismatched input '"rules"' expecting {'{', '/', PATH_SEGMENT} 3) Unexpected '}'. If you or anyone could help me out, I'd be grateful.
ncytimothy
4 years ago
For the 1st question, .updateChildValues is correct For the 2nd, not sure if you are using Cloud Firestore instead of the Realtime Database. Those are different things. A sample rules from Google gives me a hint for the "match" error message: service cloud.firestore { match /databases/{database}/documents { match /{document=**} { allow read, write: if false; } } }
ncytimothy
4 years ago
Please try and switch to Realtime Database and in the Database tab on Firebase. Hope that helps.
Akinwehinmi Rotimi Joshua
4 years ago
Please does anybody have the issues of the simulator not displaying the images picked from gallery
hughpaud@gmail.com
4 years ago
I am having the same issue and can not find the solution in the simulator.
Brian Voong
4 years ago
hughpaud@gmail.com
4 years ago
No error pops up on my build but the button will not change. The click actions carry out as if the process is working but when the image is selected it the plus photo button does not change
hughpaud@gmail.com
4 years ago
No error comes up but here is the code I named my plus photo button profile button. The steps go through but no change. class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate { //Implement design of profile photo button let profileButton: UIButton = { let button = UIButton(type: .system) button.setImage(UIImage(named: "plus_photo")?.withRenderingMode(.alwaysOriginal), for: .normal) button.addTarget(self, action: #selector(handlePlusPhoto), for: .touchUpInside) button.translatesAutoresizingMaskIntoConstraints = false return button }() @objc func handlePlusPhoto() { let imagePickerController = UIImagePickerController() imagePickerController.delegate = self imagePickerController.allowsEditing = true present(imagePickerController, animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage { profileButton.setImage(editedImage, for: .normal) } else if let oriiginalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage { profileButton.setImage(oriiginalImage, for: .normal) } profileButton.layer.cornerRadius = profileButton.frame.width/2 profileButton.layer.masksToBounds = true profileButton.layer.borderColor = UIColor.black.cgColor profileButton.layer.borderWidth = 3 dismiss(animated: true, completion: nil) }
hughpaud@gmail.com
4 years ago
I found the issue with my code. On imagePickerController function it should be @objc func imagePickerController not just func
JayR
3 years ago
To anyone unable to see their photo it may be due to the switch of versions of firebase from this video to the last. I was able to see how he fixed it in his latest uploaded project. You guys need to make sure you are changing the func imagePickerController(_ picker: UIImagePickerContrller, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]){} In those parameters the biggest change is that it is no longer a string and you now have the .InfoKey This will allow you for the original and edited image to change it to if let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage { and else if let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
iiKvs4
4 years ago
hi Brian if i choose username like this "eeee" and another user choose username like me "eeee" database just Update how to show user this username "eeee" is taken?
Brian Voong
4 years ago
Mazin
4 years ago
Is There Update Using Php for Backend Not Firebase ??
Dino32
4 years ago
Hi Brain! This error pops up even if enter more the 6 characters. Please give me advice how to fix it. Failed to create user: Error Domain=FIRAuthErrorDomain Code=17026 "The password must be 6 characters long or more." UserInfo={NSLocalizedDescription=The password must be 6 characters long or more., FIRAuthErrorUserInfoNameKey=ERROR_WEAK_PASSWORD, error_name=ERROR_WEAK_PASSWORD, NSLocalizedFailureReason=Password should be at least 6 characters}
Dino32
4 years ago
Hi Brain! I solve the previous problem with password it was my mistake in code.
Dino32
4 years ago
Hi Brain I have an error like - Failed to save user info into db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied} Just in case I've replaced all my code from mine to yours but it still does not work. How can I resolve this issue ?
Dino32
4 years ago
I figure out the problem was that I had to set up the permissions in db
Egya Eshun
4 years ago
Hello brian please let me know nif you accept bitcoin for course purchasing, thank you.
Brian Voong
4 years ago
Lavyox DWz
4 years ago
Hello brain, I've been working in problem for days now i couldn't solve it .. which is getting downloadURL, and updating the database after including the downloadURL in the dictionary .. I downloaded the project and copied the function and i still get the same problem ~_~
Brian Voong
4 years ago
Lavyox DWz
4 years ago
no I tried doing it by taking it in a different function and then call the function to get it but it returns nil
Lavyox DWz
4 years ago
should i continue the course without solving this problem . .?
YassineDaoudi
4 years ago
Hey brian i have the same problem !
Brian Voong
4 years ago
YassineDaoudi
4 years ago
I did download the latest version of Firebase but it seems that "guard let uploadData = image.jpegData(compressionQuality: 0.3) else {return}" doesn't work anymore
YassineDaoudi
4 years ago
sorry i meant " guard let profileImageUrl = metadata?.downloadURL().absoluteString else {return}"
Brian Voong
4 years ago
YassineDaoudi
4 years ago
the error i get "Value of type 'StorageMetadata' has no member 'downloadURL'"
Brian Voong
4 years ago
YassineDaoudi
4 years ago
i tried to do it like it but it didn't work ?? "Storage.storage().reference().child("profile_images").child(filename).putData(uploadData, metadata: nil) { (metadata, err) in if let err = err { print("Failed to upload profile image:", err) return } print("insode putData") metadata?.storageReference?.downloadURL(completion: { (url, error) in print("insode Download url") if let err = error{ // error happened - implement code to handle it print(err) } else { // no error happened; so just continue with your code print(url?.absoluteString) // this is the actual download url - the absolute string } }) "
YassineDaoudi
4 years ago
it worked ! thanks Brian (y)
Lavyox DWz
4 years ago
hi brain, Thank you for your help .. i find you course very informative though I'm just in the beginning so Thank you :D . . I actually found another way to do it by adding pod 'FirebaseUI/Storage' and installing it and saving the full path of the picture in the database .. it worked ,, it was nice and simple .. i saw it in firebase documentation [Link: https://firebase.google.com/docs/storage/ios/download-files?authuser=0 ].. but is it better to use downloadURL over this other way or it makes no different in the long run ?
Lucrecio909
4 years ago
I got this error "Cannot subscript a value of type '[String : Any]' with an index of type 'UIImagePickerController.InfoKey'" in my didFinishPickingMediaWithInfo func. This is the fix I found below: func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let editedImage = info[.editedImage] as? UIImage { plusPhotoButton.setImage(editedImage.withRenderingMode(.alwaysOriginal), for: .normal) } else if let originalImage = info[.originalImage] as? UIImage { plusPhotoButton.setImage(originalImage.withRenderingMode(.alwaysOriginal), for: .normal) } dismiss(animated: true, completion: nil) }
el
2 years ago
thank you
Lucrecio909
4 years ago
This call has also changed: guard let uploadData = UIImageJPEGRepresentation(image, 0.3) else { return } changed to: guard let uploadData = image.jpegData(compressionQuality: 0.3) else { return }
Lucrecio909
4 years ago
Here is a fix for this FireBase Database error "Failed to save user info into db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied}" change the rules on the RealTime Database from { "rules": { ".read": false, ".write": false } } Change it to { "rules": { ".read": true, ".write": true } }
Kalp Lathia
4 years ago
Can anyone please sand the perfectly running code of handleSignUp() function. I Tried all the solutions below and i was not able to save details of user to database. So please send the code snippet for the handleSignUp Function.
Kalp Lathia
4 years ago
i Forget to mention that the main issue strated after the profile picture came to scene. And also username is being saved to db but profilePictureURL is not getting saved there.
Brian Voong
4 years ago
Kalp Lathia
4 years ago
Ya but i am bit confused, so if u will be able to present me the code snippet for handleSignUp() function i can get myself clear with issues.
Kalp Lathia
4 years ago
Hey can you please let me provide with the code snippet, please ....
hwatanabe9393
4 years ago
damn firebase in 30 minutes :D
MaxApp
4 years ago
Hey Brian, when are you going to publish your backend course?
Brian Voong
4 years ago
kayy1898
4 years ago
Hi! I'm unable to downloadURL. Using storageRef.downloadURL(completion: { (downloadURL, err) in I researched a little and found Firebase got rid of "downloadURL"? Can you please update this line of code? Been stuck on it for a few days :(
kayy1898
4 years ago
I copied and pasted the code, and the first error was "use of unresolved identifier 'storageRef' ", so I changed it to StorageReference. I get this error when trying to downloadURL: Instance member 'downloadURL' cannot be used on type 'StorageReference'; did you mean to use a value of this type instead? I just wanted to clarify the issue
Brian Voong
4 years ago
kayy1898
4 years ago
Hi! I downloaded the updated project and copied/pasted. However, I get an error with "storageRef" that disappears when I change it to StorageReference. "downloadURL" still cannot be used, is there an updated code that I'm missing? // Firebase 5 Update: Must now retrieve downloadURL storageRef.downloadURL(completion: { (downloadURL, err) in if let err = err { print("Failed to fetch downloadURL:", err) return } guard let profileImageUrl = downloadURL?.absoluteString else { return } print("Successfully uploaded profile image:", profileImageUrl) guard let uid = user?.user.uid else { return } let dictionaryValues = ["username": username, "profileImageUrl": profileImageUrl] let values = [uid: dictionaryValues] Database.database().reference().child("users").updateChildValues(values, withCompletionBlock: { (err, ref) in if let err = err { print("Failed to save user info into db:", err) return } print("Successfully saved user info to db") }) }) }) }) }
Clint Larenz Nurse
4 years ago
When I try to update a profile image in edit profile I get URL Scheme must be one of Gs://, http:://, or Https:// Do you know what i am doing wrong?
Clint Larenz Nurse
4 years ago
Here’s the code I got func updateProfileImage() { guard imageChanged == true else { return } guard let currentUid = Auth.auth().currentUser?.uid else { return } guard let user = self.user else { return } Storage.storage().reference(forURL: user.profileImageUrl).delete(completion: nil) let filename = NSUUID().uuidString guard let updatedProfileImage = profileImageView.image else { return } guard let imageData = updatedProfileImage.jpegData(compressionQuality: 0.3) else { return } STORAGE_PROFILE_IMAGES_REF.child(filename).putData(imageData, metadata: nil) { (metadata, error) in if let error = error { print("Failed to upload image to storage with error: ", error.localizedDescription) } STORAGE_PROFILE_IMAGES_REF.downloadURL(completion: { (url, error) in USER_REF.child(currentUid).child("profileImageUrl").setValue(url?.absoluteString, withCompletionBlock: { (err, ref) in guard let userProfileController = self.userProfileController else { return } userProfileController.fetchCurrentUserData() self.dismiss(animated: true, completion: nil) }) }) } } }
Brian Voong
4 years ago
Clint Larenz Nurse
4 years ago
Thanks Brain, worked like a charm. I've been working on this project for almost a year. How can I submit to to you for a review? Or would you prefer a test flight first? I think you'll be impressed!
Chad-michael Muirhead
4 years ago
yo i used to use "!" all the time but ur vids convince me not to ..yo thanks! much respect from Jamaica
Keith Tung
4 years ago
I followed your code , but I can't change the image of the button.
jdhindsa
4 years ago
Why is all the Firebase code not actually working? For example, there is no FIRDatabase... instead I had to use: var ref: DatabaseReference! ref = Database.database().reference() Just trying to understand why the video content seems to be out of date?
Brian Voong
4 years ago
jdhindsa
4 years ago
Thanks Brian, I guess I have to keep the project you attached to each section handy.
jdhindsa
4 years ago
Do you have to create the Firebase database yourself in the dashboard or is the application creating it? I'm getting the following error when I try to create a user: Successfully created user: QzAKtDjmxQcVkPXoyary5s0lC4G2 Failed to upload profile image: Error Domain=FIRStorageErrorDomain Code=-13010 "Object profile_images/F24F5F2E-8106-4C12-A8A2-8498DF24C297 does not exist." UserInfo={object=profile_images/F24F5F2E-8106-4C12-A8A2-8498DF24C297, ResponseBody={ "error": { "code": 404, "message": "Not Found. Could not access bucket instagramfirebase-9863e.appspot.com", "status": "ACCESS_BUCKET" } }, bucket=instagramfirebase-9863e.appspot.com, data=<7b0a2020 22657272 6f72223a 207b0a20 20202022 636f6465 223a2034 30342c0a 20202020 226d6573 73616765 223a2022 4e6f7420 466f756e 642e2020 436f756c 64206e6f 74206163 63657373 20627563 6b657420 696e7374 61677261 6d666972 65626173 652d3938 3633652e 61707073 706f742e 636f6d22 2c0a2020 20202273 74617475 73223a20 22414343 4553535f 4255434b 4554220a 20207d0a 7d>, data_content_type=application/json; charset=UTF-8, NSLocalizedDescription=Object profile_images/F24F5F2E-8106-4C12-A8A2-8498DF24C297 does not exist., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=404}
Brian Voong
4 years ago
hflournoy
4 years ago
Hi Brian! Dope training thus far. I'm jammed up a little bit here with the new Firebase. I'm not exactly sure how to setup the database. Your videos thus far seem to indicate that the older version of Firebase automatically setup the database as I don't think you showed that. That said, with the new Firebase, it looks like you have to manually setup your db similar to your reply below to jdhindsa regarding the Firebase Storage. I've already setup the Storage. Reference code is identical. Here's my console output: Successfully uploaded profile image: https://firebasestorage.googleapis.com/v0/b/*****.appspot.com/o/profile_images%2FD1E65ED5-3269-4800-8335-64B86670AAC5?alt=media&token=92b3ffc4-a507-487e-8d23-08481524950a Failed to save user info into db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied} 2019-09-11 22:08:05.607901-0500 *******[27208:2795088] 6.8.0 - [Firebase/Database][I-RDB038012] updateChildValues: at /users failed: permission_denied Kind regards, champe
Brian Voong
4 years ago
hflournoy
4 years ago
Did that Brian, but it looks as if we now have to manually setup the constructs within the Real Time DB...any insight on the relational structure given we only have picture, name, UN and password right now?
Brian Voong
4 years ago
johnicode101
3 years ago
i just did and it worked for me
johnicode101
3 years ago
im struggling to set the rules for the database because i cant save data on to the data base: Failed to save user info into db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied} i keep on getting this error message. i already tried updating the firebase rules but i still get this error.
Brian Voong
3 years ago
Brandon.zappia
3 years ago
Can someone help im getting a error 'UIImage?' is not convertible to 'UIImage'
Brian Voong
3 years ago
abreyXo
3 years ago
Hey Brian, Within my stimulator I'm trying to zoom in and out of the image but I can't seem to do so. How can I resolve this? Thanks in advance :)
Brian Voong
3 years ago
ericm
3 years ago
Brian, Quality content and I love your teaching style; wish I had found you sooner. I understand that this is an older tutorial, and that you have made an effort to update code. Firebase is not cooperating. I tried starting with the older database there, and have one initiated. Do I need to name it correctly, or should it populate automatically, with the code you have posted, as current? Here's my, relevant, error output: Successfully created user Successfully uploaded profile image: https://firebasestorage.googleapis.com/v0/b/platewarsapp.appspot.com/o/profile_images%2F8A19E6CB-B2F0-43AA-AFEA-B8E8639AF274?alt=media&token=9885459d-3b50-418b-ae31-b01843f66ca4 2020-02-13 17:04:33.027675-0800 plateWars[17055:449221] 6.15.0 - [Firebase/Database][I-RDB038012] updateChildValues: at /users failed: permission_denied Failed to save user info into db: Error Domain=com.firebase Code=1 "Permission denied" UserInfo={NSLocalizedDescription=Permission denied}
ericm
3 years ago
Wait. Fixed it. Hopefully this will help others. Go to the firebase console and make certain, for this app, that you are using their older Real-Time Database. Once in the Real-Time Database console, select the rules tab and simply change read and write parameters from false to true.
pvanides
3 years ago
Thanks Eric...your fix really helped me. Thank you again!!!!
dannyp75
3 years ago
Is the project download for each video different or all the full finished project?
el
2 years ago
Having this error : Did anyone solve ? Failed to get FirebaseDatabase instance: Specify DatabaseURL within FIRApp or from your databaseForApp:URL
el
2 years ago
I solved my own problem . After creating Realtime Database and changing falseS to trueS , re-download GoogleService-Info.plist from settings and put it instead of old GoogleService-Info.plist
HELP & SUPPORT