When a user first logs into their profile, I retrieve there user name and profile picture. My issue is the site loads and firebase takes around a second to load the information. For example, there username will flash "unavailable" for a brief moment, before displaying the name.
Would love to get feedback on how to better improve my process of retrieving the information. Thank you! For the sake of less code, I didn't include my profile picture logic, as I'm guessing my issue has to do with the way I'm calling Firebase in the first place in my dashboard logic class.
struct UserDashController: View {
@ObservedObject var vm = DashboardLogic()
@State private var action: Int? = 0
@State private var userSigningOut = false
@State private var showMenu = false
@State private var presentSettingsPage = false
var body: some View {
NavigationView{
VStack{
HStack{
//retrieve username
Text(vm.userModel?.name ?? "Name Unavailable" )
}
.padding()
}
.padding(.top, -5)
}
}
Dashboard Logic
class DashboardLogic: ObservableObject {
@Published var userModel: UserModel?
@Published var privateUserModel: privateUserModel?
init(){
fetchCurrentUser()
}
private func fetchCurrentUser () {
guard let uid = FirebaseManager.shared.auth.currentUser?.uid else {
return
}
guard let email = FirebaseManager.shared.auth.currentUser?.email else {
print("could not locate email")
return
}
FirebaseManager.shared.firestore
.collection("users").document(uid)
.getDocument { snapshot, error in
if let error = error {
print ("failed to fetch user \(error)")
return
}
guard let data = snapshot?.data() else {
print ("no data found for user")
return
}
self.userModel = .init(data: data)
}
//save to private database
FirebaseManager.shared.firestore
.collection("users").document(uid)
.collection("privateUserInfo")
.document("private")
.getDocument { snapshot, error in
if let error = error {
print("oh no we messed up")
return
}
//save snapshot of database from firestore
guard let userEmail = snapshot?.data() else {
print("no email found for user")
return
}
self.privateUserModel = .init(data:userEmail )
}
}
}
USER MODEL
struct UserModel {
var uid, name, gender, height, weight, agenda, profilePictureURL: String
init(data: [String: Any]){
self.uid = data["uid"] as? String ?? "Unavailable"
self.name = data["name"] as? String ?? "Unavailable"
self.gender = data["gender"] as? String ?? "Unavailable"
self.height = data["height"] as? String ?? "Unavailable"
self.weight = data["weight"] as? String ?? "Unavailable"
self.agenda = data["agenda"] as? String ?? "Unavailable"
self.profilePictureURL = data ["profilePicture"] as? String ?? "Unavailable"
}
}
struct privateUserModel {
var email: String
init(data: [String: Any]){
self.email = data["email"] as? String ?? "Unavailable"
}
}
CodePudding user response:
The only I would change is to update published properties on main queue, like
DispatchQueue.main.async {
self.userModel = .init(data: data)
}
// ...
DispatchQueue.main.async {
self.privateUserModel = .init(data:userEmail )
}
everything else I assume is just network delays.
CodePudding user response:
From a Cloud Firestore configuration perspective, you can improve your process of retrieving the information following the best practices as:
Selecting the database location closest to your users and compute resources. Far-reaching network hops are more error-prone and increase query latency.
Considering document IDs, Field Names and Indexes to reduce latency. Improving your write and read operations practices.
Controlling the number of Cloud Functions operations.
You may also be interested in looking into this other case.