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

Viewed 93

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)
            }
        })
    }
}
1 Answers

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)
            }
    }
}
Related