首页 > 解决方案 > 立即更新信息,但前提是在数据库 swift/firebase 中进行了更改

问题描述

在我的应用程序中,我有一个显示新闻的地方,位于 4 个选项卡视图之一中。为了更改信息,与其相关的所有方面都存储在 Firestore 中(标题、副标题、文本)。目前,我正在使用addSnapshotListener来获取数据,因为每当我更改 firestore 中的数据时,它都会自动立即更新。但是,每次用户单击与新闻视图相关的选项卡视图图标时,都会执行不同的读取数据调用。我知道当用户群增长时会导致大量读数,从而导致每月向 Firebase 支付更高的费用,并且可能会延迟,对吗?为了解决这个问题,我想到的唯一解决方案是addSnapshotListener改为getDocuments. 但是,如果我对 Firestore 进行任何更改,用户需要关闭应用程序然后打开它以查看更新的信息。有没有办法立即更新信息,但前提是在数据库中进行了更改?

这就是我从 Firestore 获取信息的方式:

struct Info: Identifiable{
var id: String = UUID().uuidString
var title: String
var subtitle: String
}



class InfoViewModel: NSObject, ObservableObject {
@Published var infos = [Info]()
func fetchData(){
    Firestore.firestore().collection("infos").addSnapshotListener { (querySnapshot, error) in
        guard let documents = querySnapshot?.documents else {return}
        self.infos = documents.compactMap { (queryDocumentSnapshot) -> Info? in
            let data = queryDocumentSnapshot.data()
            
           if let title = data["title"] as? String,
              let subtitle = data["subtitle"] as? String{
            print("info successful")
            return Info(title: title, subtitle: subtitle)
           }
           else{
            print("info failed")
            return nil
           }
        }
    }
  }

  }

在我想显示信息的视图中,我有@ObservedObject var infoModel = InfoViewModel()一个ForEach来显示数据,然后.onAppear(){self.infoModel.fetchData()}

每次单击 tabView 图标时更改到此视图时,我都会在调试时获得 3x "信息成功,因为我在 infos 集合中存储了 3 个文档。

标签栏视图:

struct TabBar: View{

@State var current = 0
@StateObject var LocationModel = LocationViewModel()
var body: some View{
    NavigationView{
    TabView(selection: $current) {
        
        HomeView()
            .tag(0)
            .tabItem {
                Image(systemName: "house")
                Text("início")
            }
        SearchView(LocationModel: LocationModel)
            .tag(1)
            .tabItem {
                Image(systemName: "magnifyingglass")
                Text("buscar")
            }
        CalendarView()
            .tag(2)
            .tabItem {
                Image(systemName: "calendar")
                Text("histórico")
            }
        AccountView()
            .tag(3)
            .tabItem {
                Image(systemName: (self.current == 3 ? "person.fill" : "person"))
                Text("perfil")
            }
  
    }.accentColor(Color("Color"))
}
  }
  }

显示风暴数据的位置:

struct HomeView: View{

@StateObject var LocationModel = LocationViewModel()
@StateObject var model = ModelData()
@ObservedObject var infoModel = InfoViewModel()


var body: some View{
 
            VStack( spacing: 12) {
                  
                ScrollView(.vertical, showsIndicators: false){
                    ScrollView(.horizontal, showsIndicators: false){
                       HStack(spacing: 15){
                           ForEach(infoModel.infos){ info in
                           HStack(spacing: 20){
                           Text(info.title)
                           .frame(height: 220)
                           .frame(width: 330)
                               .background(Color.yellow)
                          .cornerRadius(18)
                           }
                       }
                                              
                       }.padding(.horizontal, 15)
                       .padding(.bottom, 25)
                    }
                    
                }
                
                .navigationBarTitle("").navigationBarHidden(true)
            }.navigationBarTitle("").navigationBarHidden(true)

         .onAppear(perform: {
            LocationModel.locationManager.delegate = LocationModel
         
            self.infoModel.fetchData()
              })
            
         .alert(isPresented: $LocationModel.alert, content: {
             
            Alert(title: Text("Mensagem"), message: Text(LocationModel.alertMsg), dismissButton: .destructive(Text("Pronto").foregroundColor(Color.blue)))
         })
     }
    
   }

标签: swiftfirebasegoogle-cloud-firestore

解决方案


您的 VC 可以引用管理与 Firestore 的所有通信的控制器。在该控制器中,您可以初始化快照侦听器。这将一次性获取您的所有文档,您可以将其作为状态存储在该控制器中。从那时起,任何 .add、.modified 和 .removed文档更改都可以更改您的控制器所持有的状态,并使用例如闭包来更新 VC。


推荐阅读