Trying To createUser with Firebase and when i am using Auth.auth().createUser(withEmail: email, password: password) give me an error - ios

enter image description here
#error >> Type of expression is ambiguous without more context.
Auth.auth().createUser(withEmail: email, password: password) { AuthDataResult, error in
// handle error
if let error = error {
print("Failed to create a user with error", error.localizedDescription)
return
}
// set profile image
guard let profileImage = self.plusPhotoButton.imageView?.image else { return }
//upload data
guard let uploadData = profileImage.jpegData(compressionQuality: 0.3) else { return }
// place image in database
let filename = NSUUID().uuidString
let storageRef = Storage.storage().reference().child("profile_image").child(filename)
storageRef.putData(uploadData, metadata: nil, completion: {(metadata, error) in
// handle error
if let error = error {
print("Faild to upload image to firebase storage with error", error.localizedDescription)
}
// profile image URL
guard let profileImageURL = metadata?.downloadURL()?.absoluteString else { return }
//user Id
guard let uid = AuthDataResult?.user.uid else { return }
//guard let fcmToken = messaging.messagin().fcmToken else { return }
let dictionaryValues = ["name": fullName,
"username": username,
"profileImageURL": profileImageURL]
let values = [uid: dictionaryValues]
//save data info to database
Database.database().reference().child("users").updateChildValues(values, withCompletionBlock: { (error, ref) in
print("Successfully created user and saved indformation to database")
})
})
}
i import Firebase but still not working.

Related

Trying to add an image to Firebase storage then add the image location to a Firestore document

I am trying to add an image to Firebase storage and then get the location of that image and store it in a Firestore document with the other user profile data. I am trying to do all of this when the user first creates an account. I was trying to use the image URL to do this but that does not appear to be working. When I run the code below it will sign up a new user and add the photo to Firebase storage but no document gets created in the Firestore database. What am I doing wrong?
#objc func handleSignUp() {
//Signup properties
guard let email = emailTextField.text else { return }
guard let password = passwordTextField.text else { return }
guard let fullName = fullNameTextField.text else { return }
guard let username = usernameTextField.text?.lowercased() else { return }
createUser(email: email,
password: password,
fullName: fullName,
userName: username)
}
func createUser(email: String, password: String, fullName: String, userName: String) {
Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
//Handle error
if let error = error {
print("DEBUG: Failed to create user with error: ", error.localizedDescription)
return
}
guard let profileImg = self.plusPhotoBtn.imageView?.image else { return }
guard let uploadData = profileImg.jpegData(compressionQuality: 0.3) else { return }
let userID = Auth.auth().currentUser!.uid
let filename = NSUUID().uuidString
//Storage location for photo in Firebase
let storageRef = Storage.storage().reference().child("profile_images").child(userID).child(filename)
storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in
//Handle error
if let error = error {
print("Failed to upload image to Firebase Storage with error", error.localizedDescription)
return
}
guard metadata != nil else { return }
let path = storageRef.fullPath;
guard let username = self.usernameTextField.text?.lowercased() else { return }
storageRef.downloadURL { (url, _) in
let data = ["name": fullName,
"username": username,
"profileImagePath": path,
"email" : email] as [String : Any]
self.addDocument(userData: data)
}
})
}
}
I think you should add the "downloadURL" part inside the "putData".
After completion of the put data process you should try to get the URL or else it will fail.
Try this and see if it works:
#objc func handleSignUp() {
//Signup properties
guard let email = email.text else { return }
guard let password = password.text else { return }
guard let fullName = name.text else { return }
guard let username = name.text?.lowercased() else { return }
createUser(email: email,
password: password,
fullName: fullName,
userName: username)
}
func createUser(email: String, password: String, fullName: String, userName: String) {
Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
//Handle error
if let error = error {
print("DEBUG: Failed to create user with error: ", error.localizedDescription)
return
}
guard let profileImg = self.plusPhotoBtn.imageView?.image else { return }
guard let uploadData = profileImg.jpegData(compressionQuality: 0.3) else { return }
let filename = NSUUID().uuidString
//Storage location for photo in Firebase
let storageRef = Storage.storage().reference().child("profile_images").child(filename)
storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in
//Handle error
if let error = error {
print("Failed to upload image to Firebase Storage with error", error.localizedDescription)
return
}
guard let metadata = metadata else { return }
guard let username = self.usernameTextField.text?.lowercased() else { return }
storageRef.downloadURL { (url, _) in
guard let downloadURL = url else {
print("DEBUG: Profile image url is nil")
return
}
let data = ["name": fullName,
"username": username,
"profileImageUrl": downloadURL,
"email" : email]
self.addDocument(userData: data)
}
})
}
}
func addDocument(userData: [String: Any]) {
Firestore.firestore().collection("profile_data").addDocument(data: userData) { (err) in
if let err = err {
debugPrint("Error adding document: \(err)")
} else {
self.navigationController?.popViewController(animated: true)
}
}
}

Not sure where in code to place storageRef.downloadURL

After updating Firebase to Version 4 and correcting all 200 errors, I am left with 2 warnings which make my app crash. I looked up this error and tried the resolution with no success:
storageReference.downloadURLWithCompletion()
I must be doing it wrong:
func setUserInfo(_ user: User!, usersname: String, email: String, password: String, cell: String, data: Data!) {
// Create Path for User Image
let imagePath = "images/riders/\(user.uid)/Profile Pic/userPic.jpg"
// Create image Reference
let imageRef = rDataService.Instance.storageRef.child(imagePath)
// Create Metadata for the image
let metaData = StorageMetadata()
metaData.contentType = "image/jpeg"
// Save the user Image in the Firebase Storage File
imageRef.putData(data as Data, metadata: metaData) { (metaData, error) in
if error == nil {
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = usersname
changeRequest.photoURL = metaData?.downloadURL()
changeRequest.commitChanges(completion: { (error) in
if error == nil {
self.saveUser(user, usersname: usersname, email: email, password: password, cell: cell)
} else {
print(error!.localizedDescription)
}
})
} else {
print(error!.localizedDescription)
}
}
}
The error is happening on this line:
changeRequest.photoURL = metaData?.downloadURL()
Edit
After adjustments, getting warning on this line:
if let profilepicMetaData = profilepicMetaData {
error: Value 'profilepicMetaData' was defined but never used; consider replacing with boolean test
App is still crashing:
// Save the user profile Image in the Firebase Storage File
imageRef.putData(data as Data, metadata: profilepicMetaData) { (profilepicMetaData, error) in
if let profilepicMetaData = profilepicMetaData {
imageRef.downloadURL(completion: { (url, error) in
guard let url = url else {
if let error = error {
print(error)
}
return
}
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = usersname
changeRequest.photoURL = url
changeRequest.commitChanges(completion: { (error) in
if error == nil {
self.saveUser(user, usersname: usersname, email: email, password: password, year: year, makeAndModel: makeAndModel, cell: cell, plateNo: plateNo)
} else {
print(error!.localizedDescription)
}
})
})
} else {
print(error!.localizedDescription)
}
}
Crash!
You need to use the original storage reference object imageRef to obtain the download url. (please check the comments through the code):
imageRef.putData(data, metadata: profilepicMetaData) {
// use if let to unwrap the metadata returned to make sure the upload was successful. You can use an underscore to ignore the result
if let _ = $0 {
// start the async method downloadURL to fetch the url of the file uploaded
imageRef.downloadURL {
// unwrap the URL to make sure it is not nil
guard let url = $0 else {
// if the URL is nil unwrap the error, print it
if let error = $1 {
// you can present an alert with the error localised description
print(error)
}
return
}
// your createProfileChangeRequest code needs to be run after the download url method completes. If you place it after the closure it will be run before the async method finishes.
let changeRequest = user.createProfileChangeRequest()
changeRequest.displayName = usersname
changeRequest.photoURL = url
changeRequest.commitChanges {
// unwrap the error and print it
if let error = $0 {
// again you might present an alert with the error
print(error)
} else {
// user was updated successfully
self.saveUser(user, usersname: usersname, email: email, password: password, year: year, makeAndModel: makeAndModel, cell: cell, plateNo: plateNo)
}
}
}
} else if let error = $1 {
// present an alert with the error
print(error)
}
}

Invalid call to setPhotoURL: after commitChangesWithCallback

I am trying to implement a user profile view, in which the user chooses a profile image from camera roll and a username. When everything is chosen, the user clicks on a createProfileButton that calls the following function:
#objc func createProfileButtonPressed() {
let user = Auth.auth().currentUser
let uid = Auth.auth().currentUser?.uid
let firebaseStorageRef = Storage.storage().reference().child("profile_picture").child(uid!)
let database = Firestore.firestore()
// settings for disabling warning concerning firestore
let settings = database.settings
settings.areTimestampsInSnapshotsEnabled = true
database.settings = settings
let profileChangeRequest = user?.createProfileChangeRequest()
profileChangeRequest?.displayName = self.usernameTextfield.text
if let profileImage = profilePicture, let imageData = UIImageJPEGRepresentation(profileImage, 0.1) {
firebaseStorageRef.putData(imageData, metadata: nil) { (metadata, error) in
if error != nil {
print("Error:", error!)
return
}
firebaseStorageRef.downloadURL(completion: { (url, error) in
if error != nil {
print("Error:", error!)
return
}
print("Picture URL:", url!)
profileChangeRequest?.photoURL = url
})
}
}
profileChangeRequest?.commitChanges(completion: { (error) in
if error != nil {
print("Error:", error!)
return
}
print("Profile created")
var databaseRef = database.collection("users").addDocument(data: ["uid": uid!, "email": user?.email!, "username": user?.displayName, "profileImageURL": user?.photoURL?.absoluteString], completion: { (error) in
if error != nil {
print("Error storing user", error!)
return
}
print("user successfully stored!")
})
self.navigationController?.popToRootViewController(animated: true)
})
}
I want the users email, username, uid and photoURL stored in a firestore document. However, what I get is this error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid call to setPhotoURL: after commitChangesWithCallback:.'
This happens after the popToRootViewController function gets called. Why does this error message show up although I want to set the photoURL before I commit the changes?
Just to expand on ekscrypto's comment. Your call to profileChangeRequest?.photoURL = url is taking place within the download callback, thus it going to be run after your call to commitChanges.
You need to put your commitChanges block inside your callback -
if let profileImage = profilePicture, let imageData = UIImageJPEGRepresentation(profileImage, 0.1) {
firebaseStorageRef.putData(imageData, metadata: nil) { (metadata, error) in
if error != nil {
print("Error:", error!)
return
}
firebaseStorageRef.downloadURL(completion: { (url, error) in
if error != nil {
print("Error:", error!)
return
}
print("Picture URL:", url!)
profileChangeRequest?.photoURL = url
profileChangeRequest?.commitChanges(completion: { (error) in
if error != nil {
print("Error:", error!)
return
}
print("Profile created")
var databaseRef = database.collection("users").addDocument(data: ["uid": uid!, "email": user?.email!, "username": user?.displayName, "profileImageURL": user?.photoURL?.absoluteString], completion: { (error) in
if error != nil {
print("Error storing user", error!)
return
}
print("user successfully stored!")
})
self.navigationController?.popToRootViewController(animated: true)
})
})
}
}

What does User? has no member 'profileimageView' mean?

I am unable to understand what exactly the error is trying to tell me. I tried fixing it by using self and changing classes. Still will not help. Need a guide that could help understand what exactly I am missing or doing wrong.
import UIKit
import Foundation
import Firebase
extension LoginController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{
func handleRegister(){
guard let email = emailTextField.text, let password = passwordTextField.text, let name = nameTextField.text
else {
print("This form is not valid")
return
}
Auth.auth().createUser(withEmail: email, password: password) { (self, error) in
if error != nil {
print(error!)
return
}
guard let uid = self?.uid else{
return
}
//sucessfully authenticated user
let storageRef = Storage.storage().reference()
// On the following line
if let uploadData = UIImagePNGRepresentation(self.profileImageView.image!) {
storageRef.putData(uploadData, metadata: nil, completion: { (metadata, error) in
if error != nil{
print(error)
return
}
})
}
let ref = Database.database().reference(fromURL: "https://bbooks-96cac.firebaseio.com/")
let userReference = ref.child("user").child(uid)
let values = ["name": name, "email": email]
userReference.updateChildValues(values, withCompletionBlock: {
(err, ref) in
if err != nil {
print(err)
return
}
// print("Saved user successfully into firebase DB")
})
}
dismiss(animated: true, completion: nil)
}
}
First, you are misusing the term self (I'm surprised there is no error here). You need a better variable name:
Auth.auth().createUser(withEmail: email, password: password) { (self, error) in
I would change self to user here and throughout what follows:
Auth.auth().createUser(withEmail: email, password: password) { (user, error) in
Second, user is then an Optional so you need to unwrap it:
if let uploadData = UIImagePNGRepresentation(user!.profileImageView.image!) {

How to write registered user into database in Swift?

When i select register.. the data is sent to Firebase authentication but does not store in the database? Can anyone tell me where im going wrong?
func handleRegister(){
// Validation
guard let email = emailTextField.text, let password = PassTextField.text, let name = nameTextField.text
else{
print("Please provide an Email and Password")
return
}
FIRAuth.auth()?.createUser(withEmail: email, password: password, completion: { (user: FIRUser?, error) in
if error != nil {
print(error!)
return
}
// Successfully authenticated user
// Saving Data to the Database
let ref = FIRDatabase.database().reference(fromURL: "https://chat-47e5b.firebaseio.com/")
let values = ["name": name, "email": email]
ref.updateChildValues(values, withCompletionBlock: { (err,ref)
in
if err != nil {
print(err!)
return
}
print("Saved user successfully into Firebase")
})
})
}
You are not doing it right, you should first get a reference to the db:
self.ref = FIRDatabase.database().reference()
Then:
let values = ["name": name, "email": email]
self.ref.child("users").child(user.uid).setValue(values)
As a side note, convert this:
if error != nil {
print(error!)
return
}
To this:
guard let error = error else {
print(error)
return
}

Resources