我正在创建一个应用程序,用户可以根据自己的权限访问其中的各种视图。
我使用这种方法来不断检查用户权限:
func checkPermission() {
let docRef = self.DatabaseFirestore.collection("Admins").document(phoneNumber)
docRef.getDocument{(document, error) in
guard error == nil else {
return
}
if let document = document, document.exists {
self.controlloAdmin = true
guard let data = document.data() else {
print("Document data was empty.")
return
}
self.permission = data["Permessi"] as? [Bool] ?? []
} else {
self.controlloAdmin = false
self.isRegistred = false
self.access = false
}
}
}
我不知道这是否是我能使用的最正确的函数,但它是我发现的少数几个有效的函数之一。
这是我的观点:
struct AdministratorPage: View {
@StateObject var administratorManager = AdministratorManager()
// User variables.
@AppStorage("phoneNumber") var phoneNumber: String = "" // User number.
@AppStorage("Access") var access: Bool = false
var body: some View {
administratorManager.checkPermission()
return NavigationView {
HStack {
VStack {
Text("Home")
Text(phoneNumber)
// Button to log out.
Button("Logout", action: {
self.access = false
})
Button("Alert", action: {
administratorManager.message = "Error title!"
administratorManager.message = "Error message!"
administratorManager.isMessage = true
}).alert(isPresented: $administratorManager.isMessage) {
Alert(title: Text(administratorManager.title), message: Text(administratorManager.message),
dismissButton: .default(Text("Ho capito!")))
}
}
}
}
}
}
当我把";administratorManager.checkPermission(("功能并按下";警报";按钮显示消息,但即使按下按钮,警报也不会消失。如果我不调用这个函数,一切都正常。
我该如何解决?警报能针对火球吗?有没有更合适的方法只读取一个数据?
屏幕锁定时的照片
我运行了您的代码,看到了您描述的行为。原因是函数直接在主体中调用。
如果要在打开视图时调用函数,请对该特定视图使用.onPeare函数。在您的情况下
.onAppear {
administratorManager.checkPermission()
}
以下(为我工作与你的代码(:
struct AdministratorPage: View {
@StateObject var administratorManager = AdministratorManager()
// User variables.
@AppStorage("phoneNumber") var phoneNumber: String = "" // User number.
@AppStorage("Access") var access: Bool = false
var body: some View {
return NavigationView {
HStack {
VStack {
Text("Home")
Text(phoneNumber)
// Button to log out.
Button("Logout", action: {
self.access = false
})
Button("Alert", action: {
administratorManager.message = "Error title!"
administratorManager.message = "Error message!"
administratorManager.isMessage = true
}).alert(isPresented: $administratorManager.isMessage) {
Alert(title: Text(administratorManager.title), message: Text(administratorManager.message),
dismissButton: .default(Text("Ho capito!")))
}
}
}
}
.onAppear {
administratorManager.checkPermission()
}
}
}
UPDATE:添加快照侦听器而不是轮询
您最初的方法是进行一种轮询,它不断地调用函数。请记住,当您提出Firebase请求时,将为您收到的文件收取费用。如果你进行民意调查,你会多次收到同一份文件,并为此收取费用。
对于我在这个答案中提到的例子,您只需要调用一次函数。如果您现在想从Firestore获得实时更新,可以添加快照侦听器。方法是:
func checkPermission() {
let docRef = db.collection("Admins").document(phoneNumber).addSnapshotListener() { documentSnapshot, error in //erca nella collezione se c'è il numero.
guard error == nil else {
print("ERROR.")
return
}
if let document = documentSnapshot {
self.controlloAdmin = true
guard let data = document.data() else {
print("Document data was empty.")
return
}
self.permission = data["Permessi"] as? [Bool] ?? []
} else {
self.controlloAdmin = false
self.isRegistred = false
self.access = false
}
}
}
每当Friestore中该文档上的值发生更改时,它也会在您的设备上发生更改。
最佳,Sebastian