FireDBase getDocument (querySnapshot) не работает - PullRequest
2 голосов
/ 16 апреля 2020

Я столкнулся с проблемой с моментальным снимком Firebase. Я успешно подключил свой аккаунт Fierbase к своему проекту XCode. Я способен изменять данные в моем облаке Firestore. Но я не могу это прочитать. Вот моя функция:


class UserService{
static func CheckIfMoreThanOneUserIsLoggedIn() -> Bool{
    var BoolenToReturn:Bool?
    let AuthUser = Auth.auth().currentUser
    let userId = AuthUser!.uid
    let localDeviceString = Constants.UserDefaultsStorage.string(forKey: userId)
    // LocalDeviceString is generated (20 random letters) when the user is logged in succesfully.
    //This DeviceString would be stored on one hand in the cloud on the other hand on the device.
    //When the user open the Application it checks if the localDeviceString of the cloud is the same as the String stored on the device.
    //I’m able to denie the user access through multiple devices simultaneously (-> Any imporvent is desired)
    let newUserReference = Firestore.firestore().collection("users").document(userId)
    newUserReference.getDocument {
        (querySnapshot, err) in // Code never runs the closure
        guard err != nil else {
            return
        }
        for document in querySnapshot!.data()! {
            if document.key == "RandomString" {
                let docValue:String = document.value as! String
                if docValue == localDeviceString{
                    BoolenToReturn = true
                }
                else{
                    BoolenToReturn = false
                }
            }
        }
    }

    return BoolenToReturn  ?? false
}
}

Редактировать

На основе ссылок @Frank van Puffelen я смог найти собственное решение. Но программа не так профессиональна, как я хочу, потому что теперь это функция, определенная в LaunchViewController. Кроме того, я призываю перейти к HomeViewController при закрытии newUserReference.getDocument. Чего я не хочу достичь: функция, определенная в классе UserService, которая возвращает bool, если пользователю разрешено использовать приложение.

1 Ответ

1 голос
/ 17 апреля 2020

Я думаю, что вы можете исследовать обработчик завершения. Идея состоит в том, чтобы вызвать асинхронную функцию и затем выполнить задачу, когда эта функция будет завершена. Приведенный ниже код может быть непосредственно применен в качестве решения вашего вопроса.

Итак, вот пример, с которого вы можете начать. Предположим, у нас есть приложение с пользователями, хранящимися в коллекции пользователей

users
   uid_0
      name: "Steve"
   uid_1
      name: "Danno"
   uid_2
      name: "Junior"
   uid_3
      name: "Tani"

, и новый пользователь хочет зарегистрироваться, но приложение не допускает повторяющихся имен. Поэтому нам нужно запросить нашу коллекцию пользователей, чтобы определить, используется ли уже имя. Вот код, который вызывает функцию запроса.

self.doesUserNameExist(userName: "Steve" ) { doesExist in
    if doesExist == true {
        print("yep, it exists")
    } else {
        print("Nope - it's not there")
    }
}

print("this code will execute before the above code")

Это напечатает да, он существует

и вот фактическая функция, которая выполняет запрос. Обратите внимание, что мы используем обработчик завершения, который @escaping замыкание, когда оно выполнено.

//determine if a user name exists in Firestore, return true if it does, false if not
func doesUserNameExist(userName: String, completion: @escaping( (Bool) -> Void) ) {
    let usersCollection = self.db.collection("users")
    usersCollection.whereField("name", isEqualTo: userName).getDocuments(completion: { querySnapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        guard let docs = querySnapshot?.documents else { return }

        if docs.count > 0 {
            completion(true)
        } else {
            completion(false)
        }
    })
}

Это типичный способ «возврата» данных из асинхронной функции, так как он позволяет функции выполняться, данные должны быть действительными, а затем передать эти данные обратно вызывающей функции асинхронным способом.

Обратите внимание, что любой код, следующий за вызывающей функцией, например

print("this code will execute before the above code")

, будет выполняться до код в закрытии функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...