DispatchGroup будет выходить только когда метод вызывается дважды - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь зарегистрировать пользователей с аутентификацией Firebase.Когда пользователь регистрируется, я бы хотел, чтобы его добавили в мою коллекцию Users в Firestore, а также в раздел авторизации Users.

Метод createUser(withEmail: ...) работает каждый раз.Однако мой метод db.collection("users").document(user.id).setData([..] будет вызываться только в том случае, если я дважды нажму кнопку регистрации, и в этот момент метод createUser(withEmail ...) будет вызван снова.Вот соответствующий код

RegistrationViewController.swift

@IBAction func signupButtonTapped(_ sender: UIButton) {
    // user: User() defined here

    usersHelper.signup(user: user, password: password) { result in
        // This closure is only executed on the second press
        guard let user = result as? Firebase.User else {
            let error = result as? Error
            self.handleSignupError(error!)
            return
        }
        self.performSegue(withIdentifier: "ShowGroupsFromSignupSegue", sender: self)
    }
}

UsersHelper.Swift

func signup(user: User, password: String, completion: @escaping (_ result: Any?) -> Void) {
    let userDispatchGroup = DispatchGroup()
    var signupError: Error? = nil
    var dbError: Error? = nil
    var firebaseUser: Firebase.User? = nil

    userDispatchGroup.enter()
    usersDataModel.signupUser(user: user, password: password) { result in
        // Completion handler
        if result as? Error != nil {
            signupError = result as? Error
        } else {
            // Got the user
            firebaseUser = result as? Firebase.User
        }
        userDispatchGroup.leave()
    }

    userDispatchGroup.enter()
    usersDataModel.create(user: user) { err in
        // This will only execute if signUp is called twice
        if let result = err as? Error {
            print("Error msg: \(result.localizedDescription)")
            dbError = result
        }
        print("!Created db user")
        userDispatchGroup.leave()
    }

    userDispatchGroup.notify(queue: .main) {
        print("!dispatch group completed successfully")
        if (signupError == nil && dbError == nil) {
            completion(firebaseUser)
        } else {
            signupError != nil ? completion(signupError) : completion(dbError)
        }
    }
}

UsersDataModel.swift

func signupUser(user: User, password: String, _ completion: @escaping (_ err: Any? ) -> Void) {
    // Create user in Auth & create DB entry
    Auth.auth().createUser(withEmail: user.email, password: password) { (authResult, err) in
        if let err = err {
            print("Error creating user \(err)")
            completion(err)
        } else {
            print("User signed up successfully")
            completion(authResult) // completion called with User
        }
    }
}


func create(user: User, _ completion: @escaping (_ result: Any?) -> Void) {
    // userData dictionary created here

    db.collection("users").document(user.ID).setData(userData) { err in
        if let err = err {
            print("There was an error creating the user \(err)")
            completion(err)
        } else {
            print("!User created in db successfully!")
            completion(nil)
        }
    }
}

Любая помощь с благодарностью!Спасибо всем заранее

1 Ответ

0 голосов
/ 24 мая 2018

Я исправил ошибку.Я закончил тем, что вложил второй сетевой вызов, чтобы:

  1. Получить UID от пожарного магазина, который был аутентифицирован

  2. Не нарушать правила пожарного хранилища озапись в базу данных без авторизованного uid

Мой UsersHelper.swift файл теперь выглядит как

func signup(user: User, password: String, completion: @escaping (_ result: Any?) -> Void) {
    let userDispatchGroup = DispatchGroup()
    var signupError: Error? = nil
    var dbError: Error? = nil
    var firebaseUser: Firebase.User? = nil

    userDispatchGroup.enter()
    usersDataModel.signupUser(user: user, password: password) { result in
        // Completion handler
        if result as? Error != nil {
            // there was an error?
            print("Error: \(result)")
            signupError = result as? Error
        } else {
            // Got the user
            firebaseUser = result as? Firebase.User
            // Create user entry in DB
            user.ID = firebaseUser!.uid

            self.usersDataModel.create(user: user) { err in
                // Completion handler
                if let err = err as? Error {
                    dbError = err
                }
                userDispatchGroup.leave()
                print("Done")
            }
        }
    }

    userDispatchGroup.notify(queue: .main) {
        print("!dispatch group completed successfully")
        if (signupError == nil && dbError == nil) {
            completion(firebaseUser)
        } else {
            signupError != nil ? completion(signupError) : completion(dbError)
        }
    }
}
...