I have tried many times to follow different videos on how to upload a profile photo to firebase. Currently, Auth works and creates a user with full name, uid, & password but no image URL is stored in Firestore database nor is the actual image stored in Firestore storage.
When the user hits "sign up" I'd like the account to be created as well as the image to be stored.
CreateAccountAuth View:
import SwiftUI
struct CreateAccountAuth: View {
@State private var email = ""
@State private var password = ""
@State private var fullname = ""
@Environment(\.presentationMode) var presentationMode
@EnvironmentObject var viewModel: AuthViewModel
@State private var showImagePicker = false
@State private var selectedImage: UIImage?
@State private var profileImage: Image?
var body: some View {
VStack(alignment: .leading) {
Text("Let's get started")
.font(.title)
.fontWeight(.semibold)
Button {
showImagePicker.toggle()
} label: {
if let profileImage = profileImage {
profileImage
.resizable()
.scaledToFill()
.frame(width: 100, height: 100)
.cornerRadius(10)
} else {
Image("EmptyProfile")
.resizable()
.scaledToFill()
.frame(width: 100, height: 100)
}
}
.padding(.bottom, 24)
.fullScreenCover(
isPresented: $showImagePicker,
onDismiss: loadImage) {
ImagePicker(image: $selectedImage)
}
VStack (alignment:.leading) {
CustomInputField(imageName: "person", placeholderText: "Name", text: $fullname)
.padding(.bottom, 24)
CustomInputField(imageName: "mail", placeholderText: "Email", text: $email)
.padding(.bottom, 24)
CustomInputField(
imageName: "lock",
placeholderText: "Password",
isSecureField: true,
text: $password)
}.padding(.bottom, 16)
VStack {
Button {
viewModel.register(
withEmail: email,
password: password,
fullname: fullname)
} label: {
Text("Sign Up")
.font(.headline)
.foregroundColor(.white)
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(Color.accentColor)
.clipShape(Capsule())
.padding(.vertical)
}
Text("or")
Button {
print("Continue with phone..")
} label: {
Text("Sign up with phone")
.font(.headline)
.fontWeight(.regular)
.foregroundColor(.black)
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(Color(.systemGray5))
.clipShape(Capsule())
.padding(.vertical)
}
Spacer()
Button {
presentationMode.wrappedValue.dismiss()
} label: {
HStack {
Text("Already have an account?")
.font(.footnote)
Text("Sign in")
.font(.footnote)
.fontWeight(.semibold)
}
}
.padding(.bottom, 40)
}
.padding(.top, 56)
}
.padding(.top, 40)
.navigationBarHidden(true)
.padding(.leading)
.padding(.trailing)
}
func loadImage() {
guard let selectedImage = selectedImage else { return }
profileImage = Image(uiImage: selectedImage)
}
}
struct CreateAccountAuth_Previews: PreviewProvider {
static var previews: some View {
CreateAccountAuth()
}
}
AuthViewModel View:
import SwiftUI
import FirebaseAuth
import FirebaseCore
import FirebaseStorage
import FirebaseFirestore
import FirebaseFirestoreSwift
class AuthViewModel: ObservableObject {
@Published var userSession: User?
@Published var didAuthenticateUser = false
private var tempUserSession: User?
init() {
self.userSession = Auth.auth().currentUser
print("DEBUG: User session is \(self.userSession?.uid)")
}
func login(withEmail email: String, password: String) {
Auth.auth().signIn(withEmail: email, password: password) { result, error in if let error = error {
print("DEBUG: Failed to register with error \(error.localizedDescription)")
return
}
guard let user = result?.user else { return }
self.userSession = user
print("DEBUG: Did log user in...")
}
}
func register(withEmail email: String, password: String, fullname: String) {
Auth.auth().createUser(withEmail: email, password: password) { result, error in
if let error = error {
print("DEBUG: Failed to register with error \(error.localizedDescription)")
return
}
guard let user = result?.user else { return }
self.tempUserSession = user
print("DEBUG: Registered user successfully")
print("DEBUG: User is \(self.userSession)")
let data = ["email": email,
"fullname": fullname,
"uid": user.uid]
Firestore.firestore().collection("users")
.document(user.uid)
.setData(data) { _ in
self.didAuthenticateUser = true
}
}
}
func signOut() {
//sets user session to nil so we show login view
userSession = nil
tempUserSession = nil
didAuthenticateUser = false
//signs user out on server(backend)
try? Auth.auth().signOut()
}
func uploadProfileImage(_ image: UIImage) {
guard let uid = tempUserSession?.uid else { return }
ImageUploader.uploadImage(image: image) { profileImageUrl in
Firestore.firestore().collection("users")
.document(uid)
.updateData(["profileImageUrl": profileImageUrl]) { _ in
self.userSession = self.tempUserSession
}
}
}
}