Here is the complete code:
import SwiftUI
import FirebaseAuth
import FirebaseFirestore
import FirebaseSharedSwift
struct ProfileView: View {
@State private var user: User?
@State private var isEditing = false
@State private var profilePicture: Image? = Image(systemName: "person.circle.fill")
@State private var name: String = ""
@State private var email: String = ""
@State private var phoneNumber: String = ""
@State private var bio: String = ""
private var userId: String? {
Auth.auth().currentUser?.uid
}
var body: some View {
VStack {
if let user = user {
VStack {
profilePicture?
.resizable()
.scaledToFill()
.frame(width: 100, height: 100)
.clipShape(Circle())
.overlay(Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
.padding()
Button(action: {
}) {
Text("Change Profile Picture")
.foregroundColor(.blue)
}
.padding(.bottom)
}
Form {
Section(header: Text("Profile Information")) {
TextField("Name", text: $name)
.disabled(!isEditing)
TextField("Email", text: $email)
.disabled(true) // Email is usually not editable
TextField("Phone Number", text: $phoneNumber)
.disabled(!isEditing)
TextField("Bio", text: $bio)
.disabled(!isEditing)
}
Section {
if isEditing {
Button("Save Changes") {
saveChanges()
}
Button("Cancel") {
isEditing.toggle()
loadUserData()
}
} else {
Button("Edit Profile") {
isEditing.toggle()
}
}
}
}
} else {
ProgressView("Loading profile...")
.progressViewStyle(CircularProgressViewStyle())
}
}
.onAppear {
loadUserData()
}
}
private func loadUserData() {
guard let userId = userId else { return }
let db = Firestore.firestore()
db.collection("users").document(userId).getDocument { snapshot, error in
if let error = error {
print("Error fetching user data: \(error)")
} else if let snapshot = snapshot, snapshot.exists {
do {
let fetchedUser = try snapshot.data(as: User.self)
self.user = fetchedUser
self.name = fetchedUser?.name ?? ""
self.email = fetchedUser?.email ?? ""
self.phoneNumber = fetchedUser?.phoneNumber ?? ""
self.bio = fetchedUser?.bio ?? ""
if let pictureURL = fetchedUser?.profilePictureURL {
loadProfilePicture(from: pictureURL)
}
} catch {
print("Error decoding user data: \(error)")
}
}
}
}
private func loadProfilePicture(from url: String) {
guard let url = URL(string: url) else { return }
Task {
do {
let (data, _) = try await URLSession.shared.data(from: url)
if let uiImage = UIImage(data: data) {
profilePicture = Image(uiImage: uiImage)
}
} catch {
print("Failed to load image from URL: \(error)")
}
}
}
private func saveChanges() {
guard let userId = userId else { return }
let db = Firestore.firestore()
let userRef = db.collection("users").document(userId)
let updatedUser = User(
coder: <#NSCoder#>,
id: userId,
name: name,
email: email,
phoneNumber: phoneNumber,
profilePictureURL: nil,
bio: bio
)
do {
try userRef.setData(from: updatedUser) { error in
if let error = error {
print("Error saving user data: \(error)")
} else {
print("User data successfully saved!")
}
}
} catch {
print("Error serializing user data: \(error)")
}
}
}