'Swiftui - Fetch data after login
I'm starting to learn SwiftUI and i'm looking for better solution to fetch user data after successful login.
For example, i need to see if the user has the account blocked or not after login
For this i have create struct in Users.swift
struct Users: Identifiable, Codable{
@DocumentID var id: String?
var Societe : String
var Nom : String
var Prenom : String
var HasBlocked : Bool
var SiteID : [String]
var Poste : String
var Email : String
}
and firebase class in Firebase.swift
class Firebase: ObservableObject {
@EnvironmentObject var viewRouter: ViewRouter
@Published var user : Users? = nil
private var db = Firestore.firestore()
func fetchData() {
db.collection("Users").document(Auth.auth().currentUser!.uid).addSnapshotListener{ (snapshot, error) in
guard let documents = snapshot?.data() else {
print("No documents")
return
}
let name = documents["Nom"] as? String ?? ""
let surname = documents["Prenom"] as? String ?? ""
let email = documents["Email"] as? String ?? ""
let societe = documents["Societe"] as? String ?? ""
let poste = documents["Poste"] as? String ?? ""
let siteId = documents["SiteID"] as? [String] ?? []
let hasBlocked = documents["HasBlocked"] as? Bool ?? true
if let user = self.user?.SiteID{
print(user)
}else{
print("no document2")
}
self.user = Users(Societe: societe, Nom: name, Prenom: surname, HasBlocked: hasBlocked, SiteID: siteId, Poste: poste, Email: email)
}
}
}
and in the SignInView after press login button, i call func signInUser
@ObservedObject private var firebase = Firebase()
func signInUser(userEmail: String, userPassword: String) {
signInProcessing = true
Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
guard error == nil else {
signInProcessing = false
signInErrorMessage = error!.localizedDescription
return
}
switch authResult {
case .none:
print("Could not sign in user.")
signInProcessing = false
case .some(_):
print("User signed in")
// get data and check ??
signInProcessing = false
withAnimation {
viewRouter.currentPage = .homePage
}
}
}
}
But i don't know how to fetch data after login for check if the account has blocked and then pass the data to Homeview without re-fetch data to optimize call database.
thank for your help
Solution 1:[1]
Let me address this at a high level as your code seems fine but its's just wrapping your brain around the asynchronous calls.
I am pretty sure you have everything you need - here's the flow using pseudo code
authenticate { auth closure
read user document using auth.uid { snapshot closure
if snapshot has user blocked {
do not proceed to next view
} else { //user is not blocked
proceed to next view
}
}
}
Remember that Firebase data is only valid within the closure following the Firebase call and if you follow the above pseudo code, it does just that...
auth closure - has valid firebase auth information so you can get the uid
snapshot closure - has valid snapshot info so you can see if the user is blocked
the If statement will then determine the next thing to do - either don't show
the view if blocked or show it if not blocked
So borrowing from your code
func signInUser(userEmail: String, userPassword: String) {
Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
db.collection("Users").document(Auth.auth().currentUser!.uid).getDocument {
either go to next view or not
Note that you should be using getDocument in this case to read the document once instead of adding a listener.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jay |