Firestore / Swift 4: Проверить, существует ли имя пользователя?

Я пытаюсь понять, где я могу ошибиться со следующим кодом. Я попытался найти способ проверить, содержит ли коллекция users строку в одном из документов в поле username.

Структура выглядит примерно так

#users(collection)
    #userID(document)
        #name:String
        #email:String
        #username:String
    #userID(document)
        #name:String
        #email:String
        #username:String

Я пытаюсь проверить, существует ли в users и в любом document, строка в поле username. Нашел возможное решение этого вопроса (среди прочего) здесь, вызвав функцию для запроса имени пользователя.

Я создал функцию в расширении:

extension UITextField {

    func checkUsername(username: String, completion: @escaping(Bool) -> Void) {
        let usernameRef = Database.database().reference()
        usernameRef.child("users").queryOrdered(byChild: "username").queryEqual(toValue: username).observeSingleEvent(of: DataEventType.value, with: { (snapshot: DataSnapshot) in
            if snapshot.exists() {
                completion(true)
            }
            else {
                completion(false)
            }
        })
    }

}

и вызвал его в текстовом поле в textFieldDidEndEditing, чтобы он мог выполнить проверку при попытке пользователя потребовать имя пользователя.

func textFieldDidEndEditing(_ textField: UITextField) {

    if activeField == usernameField {
        textField.checkUsername(username: usernameField.text!) { isExist in
            if isExist {
                print("Username exists")
            } else {
                print("Username does not exist")
            }
        }
    }

}

Однако это всегда возвращает 'Username does not exist' на консоль, даже если имя пользователя существует.

В настоящее время в базе данных есть 1 имя пользователя с именем test, поэтому попытка входа в тест должна вернуть 'Username exists', а ввод testtwo должен вернуть 'Username does not exist'.

Что я могу здесь упустить? Я предполагаю, что он неправильно запрашивает базу данных?

Вы отметили вопрос как Cloud Firestore, но в своем коде используете базу данных Firebase Realtime. Эти две базы данных совершенно разные, так какую из них вы используете?

Frank van Puffelen 14.07.2018 02:21

Firestore :) Я предполагаю, что здесь что-то не так, если я пытаюсь проверить базу данных в реальном времени вместо базы данных Firestore.

Jason 14.07.2018 02:36

Да, это точно не сработает. Обязательно ознакомьтесь с документацией Firestore по поводу получения документов, здесь: firebase.google.com/docs/firestore/query-data/get-data

Frank van Puffelen 14.07.2018 02:39

Спасибо! Просто взгляните сейчас, чтобы увидеть, что мне нужно изменить? В этой заметке, было бы лучше поместить все имена пользователей в отдельную коллекцию под названием «имена пользователей» при создании пользователя, поэтому мне нужно будет только запрашивать документы в коллекции, а не запрашивать каждый документ отдельно для поля, которое имеет Имя пользователя?

Jason 14.07.2018 02:48

С точки зрения производительности это будет примерно то же самое, поэтому я бы выбрал самое простое решение.

Frank van Puffelen 14.07.2018 06:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
1 509
1

Ответы 1

Спасибо Фрэнку за указание, что я звонил в базу данных реального времени, а не в Firestore. Обновил мой код, чтобы вернуть значение true или false при проверке документов на предмет чего-либо, хранящегося в 'username', и подумал, что поделюсь своим обновленным кодом, если кто-то еще попытается проверить 'usernames' в своей базе данных Firestore.

Создал расширение для UITextField, которое вызывается, когда мне нужно проверить, доступно ли имя пользователя:

func checkUsername(field: String, completion: @escaping (Bool) -> Void) {
    let collectionRef = db.collection("users")
    collectionRef.whereField("username", isEqualTo: field).getDocuments { (snapshot, err) in
        if let err = err {
            print("Error getting document: \(err)")
        } else if (snapshot?.isEmpty)! {
            completion(false)
        } else {
            for document in (snapshot?.documents)! {
                if document.data()["username"] != nil {
                    completion(true)
                }
            }
        }
    }
}

Затем на UITextFieldtextDidEndEditing я вызываю функцию, активное поле - это поле имени пользователя:

func textFieldDidEndEditing(_ textField: UITextField) {

    if activeField == usernameField {
        if textField.text?.isEmpty == false {
            textField.checkUsername(field: textField.text!) { (success) in
                if success == true {
                    print("Username is taken")
                    // Perform some action
                } else {
                    print("Username is not taken")
                    // Perform some action
                }
            }
        }
    }

} 

Затем возвращается 'Username is taken', если я пытаюсь ввести имя пользователя, которое существует в любом из полей документа username, или 'Username is not taken', если ничего не найдено.

Если у кого-то есть отзывы об улучшении кода или какие-либо вопросы, дайте мне знать. Я с радостью обновлю информацию для справки. :)

Другие вопросы по теме