I'm currently building an app and i faced some issues. I use Firebase to store the user data and then i display it in some of the views, i managed to create the function to retrieve data with completion, so the async issue is solved, but now when i need to display some of the data it displays nil, because the view is loaded sooner than the firebase loads.
My function to load data from firebase:
func getUserFromUID(completion: @escaping (UserData)->()){
ref.child("users").child(uid).observe(.value) { (snapshot) in
DispatchQueue.main.async {
guard let dictionary = snapshot.value as? [String:AnyObject] else { return}
var user = UserData()
if let email = dictionary["email"]{ user.email = email as? String }
if let name = dictionary["name"]{ user.name = name as? String }
user.firstname = (dictionary["firstname"] as! String)
user.lastname = (dictionary["lastname"] as! String)
user.type = (dictionary["type"] as! String)
user.uid = (dictionary["uid"] as! String)
user.profileImageUrl = (dictionary["profileImageUrl"] as! String)
user.id = snapshot.key
user.fcmToken2 = (dictionary["fcmToken"] as! String)
completion(user)
}
}
}
ChatsHomeView:
struct ChatsHomeView: View {
@ObservedObject var session : SessionStore
@State var user = UserData()
func getUserInfo(){
session.getUserFromUID { (fetcheduser) in
self.user = fetcheduser
print("THE USER:\(user)")
}
}
var body: some View {
VStack{
Text(user.name ?? "nil")
Button(action: {
session.signOut()
}){ Text("Logout").padding() }
}.onAppear{
getUserInfo()
}
}
}
The problem is, that once the user logins, it displays nil where the ChatsHomeView Text(user.name ?? "nil") field is. I need to restart the app for the field to update and show the Name. Is there a way to show the app launch screen until firebase fully loads, or maybe there is any other way?
CodePudding user response:
The iOS app will certainly be ready to show views before any network operation completes.
The requirement to keep a launch screen visible can be met by having the first VC's UI match the launch view. I've done this in an Objective-C app. In it, that first VC loads the launch view's nib in viewDidLoad
and sets it as the view.
The completion code for the user snapshot should then check to see if the launch UI is still visible. If it is, it can then change the UI then to one that expects the user data.
CodePudding user response:
why not to on firebase offline capability it help you out to auto sync current data and also it will not load to again and again all data
you need to enable isPersistenceEnabled
property for your firebase database
Database.database().isPersistenceEnabled = true
then you need to use keepSynced(true)
so the data will stay synchronized.
Persistence Behavior:
By enabling persistence, any data that the Firebase Realtime Database client would sync while online persists to disk and is available offline, even when the user or operating system restarts the app. This means your app works as it would online by using the local data stored in the cache. Listener callbacks will continue to fire for local updates.
keepSynced(true):
The Firebase Realtime Database synchronizes and stores a local copy of the data for active listeners. In addition, you can keep specific locations in sync.
for more info check this documentation