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