即时更新信息,但仅当在数据库swift/firebase中进行更改时

即时更新信息,但仅当在数据库swift/firebase中进行更改时,swift,firebase,google-cloud-firestore,Swift,Firebase,Google Cloud Firestore,在我的应用程序中,我有一个显示新闻的地方,位于4个选项卡视图之一。为了更改信息,与信息相关的所有方面都存储在firestore中(标题、副标题、文本)。目前,我正在使用addSnapshotListener获取数据,因为每当我在firestore中更改数据时,它都会自动立即更新。但是,每次用户单击与新闻视图相关的选项卡视图图标时,都会执行不同的读取数据调用。我知道当用户群增长时,它会导致大量读数,导致firebase每月支付更高的费用,可能会延迟,对吗?要解决这个问题,我考虑的唯一解决方案是将a

在我的应用程序中,我有一个显示新闻的地方,位于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图标切换到此视图时,我都会在调试时获得3倍的成功信息,因为我在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"))
}
  }
  }
显示firestorm数据的位置:

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)))
         })
     }
    
   }

你的VC可以引用一个控制器,该控制器管理与Firestore的所有通信。在该控制器中,你可以初始化快照侦听器。这将一次性获取你的所有文档,你可以将其作为状态存储在该控制器中。从该点开始,任何.added、.modified和.remove都可以更改你的控制器的状态使用闭包等方式对VC进行归档和更新。

您需要将ui(VC)和数据“服务”分离,它可以是一个
addSnapshotListener
并为VC保存数据display@KirilS. 嘿,谢谢你的回复。我是Firebase/Swift的新手,因此如果您有任何可以帮助我的信息链接,我将不胜感激。例如:这种问题很难回答,因为它不包含代码,所以我们不知道用例。例如,这
执行了不同的读取数据调用
——我们不知道“不同调用”是什么或做什么。我们也不知道其他代码是否也有问题。请花一点时间,回顾一下。这个问题也不清楚,也许你可以澄清一下?嘿,杰,谢谢你的反馈。刚刚添加了代码信息嘿,谢谢你的回复。我是Firebase/Swift的新手,因此如果您有任何可以帮助我的信息链接,我将不胜感激。