简体   繁体   中英

Swift message alert exit button doesn't work

I am creating an application in which a user, based on the permissions he has, can access the various views.

I use this method to constantly check user permissions:

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

I don't know if it is the most correct function I could use, but it is one of the few that I have found that works.

This is my view:

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

            }
        }
    }
}
}

When I call the "administratorManager.checkPermission()" function and press the "Alert" button the message is displayed, but even if the button is pressed the alert does not disappear. If I don't call this function, everything works.

How can I solve? Can the alert go against firebase? Is there a more suitable method to read only one data?

photo of the screen when it got locked

I ran your code and I saw the behavior you described. The reason is the function call directly in the body.

If you want to call a function when when you open a view, use the.onAppear function for that specific view. In your case

.onAppear {
    administratorManager.checkPermission()
}

The following (worked for me with you code):

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: add Snapshot listener instead of polling

Your initial approach was doing a kind of polling, it called the function constantly. Please keep in mind, when you do a Firebase request, you will be billed for the documents you get back. If you do the polling, you get the same document multiple times and will be billed for it.

With my above mentioned example in this answer, you just call the function once. If you now want to get the live updated from Firestore, you can add a snapshot listener. The approach would be:

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

Whenever a value changed on that document in Friestore, it'll be changed on your device as well.

Best, Sebastian

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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