简体   繁体   English

等待firebase加载直到显示View

[英]Wait for firebase to load until showing View

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.我使用 Firebase 来存储用户数据,然后在一些视图中显示它,我设法创建了 function 来检索完成的数据,所以异步问题解决了,但是现在当我需要显示它的一些数据时显示 nil,因为视图的加载速度早于 firebase 次加载。

My function to load data from firebase:我的function从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.问题是,一旦用户登录,它会在 ChatsHomeView Text(user.name?? "nil") 字段所在的位置显示 nil。 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?有没有办法在 firebase 完全加载之前显示应用程序启动屏幕,或者还有其他方法?

The iOS app will certainly be ready to show views before any.network operation completes. iOS 应用程序肯定会在任何网络操作完成之前准备好显示视图。

The requirement to keep a launch screen visible can be met by having the first VC's UI match the launch view.让第一个 VC 的 UI 与启动视图匹配可以满足保持启动屏幕可见的要求。 I've done this in an Objective-C app.我在 Objective-C 应用程序中完成了此操作。 In it, that first VC loads the launch view's nib in viewDidLoad and sets it as the view.在其中,第一个 VC 在viewDidLoad中加载启动视图的笔尖并将其设置为视图。

The completion code for the user snapshot should then check to see if the launch UI is still visible.然后,用户快照的完成代码应检查启动 UI 是否仍然可见。 If it is, it can then change the UI then to one that expects the user data.如果是,则它可以将 UI 更改为需要用户数据的 UI。

edit Illustration from an Objective-C project:编辑来自 Objective-C 项目的插图:

In the first VC designated in the main storyboard, grab the UI from your app's launch storyboard and temporarily cover your view with it.在主 storyboard 中指定的第一个 VC 中,从您的应用程序启动 storyboard 中获取 UI,并暂时用它覆盖您的视图。 The user perception will be that the launch is still happening.用户认为发布仍在进行中。 Kick off the async work.开始异步工作。 When it completes, change the UI back...完成后,将 UI 改回...

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *storyboardName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
    UINavigationController *vc = [storyboard instantiateViewControllerWithIdentifier:@"LaunchVC"];
    UIView *launchView = vc.view;
    
    [self.view addSubview:launchView];
    [self startObserving:^(FIRDocumentSnapshot *snapshot, NSError *error) {
        if (!error) {
          // the async work has completed
          // setup this VC's underlying view with data from the snapshot, then uncover it
          [launchView removeFromSuperview]; 
        }
    }];
}

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为什么不打开 firebase 离线功能,它可以帮助您自动同步当前数据,而且它不会一次又一次地加载所有数据

you need to enable isPersistenceEnabled property for your firebase database您需要为 firebase 数据库启用isPersistenceEnabled属性

Database.database().isPersistenceEnabled = true

then you need to use keepSynced(true) so the data will stay synchronized.那么您需要使用keepSynced(true)以便数据保持同步。

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.通过启用持久性,Firebase 实时数据库客户端在联机时同步的任何数据都会保留到磁盘并可脱机使用,即使在用户或操作系统重新启动应用程序时也是如此。 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. Firebase 实时数据库同步并存储活动侦听器的数据本地副本。 In addition, you can keep specific locations in sync.此外,您可以使特定位置保持同步。

for more info check this documentation有关更多信息,请查看此文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM