0

I'm using Firebase to register and login (email/password) users. The registration flow is for a user to sign up with the form in the app, verify their email (done by firebase), and then wait to have their account activated manually.

When the user registers, it creates a new document in 'Users' collection, with the information they provided at registration, and by default sets IsActiveUser to false.

When a user successfully logs in, two checks are made - one that Auth.auth().currentuser?.isEmailVerified is true (this part works), and another retrieves the user's information from the 'Users' collection, and checks if the field isActiveUser is true (this part doesn't).

I have added two print() statements to track the variable, and it works when the document is retrieved by docRef.getDocument, but then reverts to nil outside prior to the if statement verifications.

struct LoginView:View {
    @State private var isActive: Bool?

    Button("Login", action: {
        Auth.auth().signIn(withEmail: userEmail, password: userPass) { authresult, error in
            if let e = error {
                //display error
            } else {
                // User has correct user/pass
                let userID = Auth.auth().currentUser?.uid
                let docRef = db.collection("Users").document(userID!)
                docRef.getDocument { (document, error) in
                    if let document = document, document.exists {
                        print(document.data()!)
                        isActive = document.data()!["isActiveUser"]! as? Bool
                        print("Inside if/let: \(isActive)") //this seems to work, and pulls the correct information
                    } else {
                        print("Document does not exist")
                    }
                }
                print("Before validation \(isActive)") //here it prints nil
                
                if Auth.auth().currentUser?.isEmailVerified == false {
                    // Email address needs to be verified. Alert user and signs out. This works.
                } else if isActive == false {
                    // Account has not been activated by administrator. Alert user and signs out. This does not work.
                } else {
                    // User is successfully logged in.
                }
            }
        }
    }).buttonStyle(BrandButtonStyle())
        .alert(isPresented: $showingAlert) {
            Alert(title: Text(errorTitle), message: Text(errorText), dismissButton: .default(Text("OK")))
        }

}

Output:

Before validation nil
["userEmail": foo@bar.com, "userID": moAyFkkhd9gXDpnRZwadHc5rtL22, "isActiveUser": 0, "userName": Foo Bar]
Inside if/let: Optional(false)
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
stygarfield
  • 107
  • 9

1 Answers1

0

As @jnpdx mentioned, getDocument is asynchronous. After reading through the link they provided I moved all of the login verification inside of the closure, and now logging in works as expected!

stygarfield
  • 107
  • 9