Firebase не отправляйте мне мои значения в мою переменную - PullRequest
0 голосов
/ 29 декабря 2018

У меня есть код, который обычно должен возвращать мне значение из Firebase.

Моя структура Firebase:

Experience{
    UserId{
        LDG_DAY: "4"
        LDG_NIGHT: "0"
        APCH_IFR: "0"
    }
}

Мой код:

func getUserExp(){
    let ref = Database.database().reference()
    let userID = Auth.auth().currentUser?.uid
    let Date = self.flightDate.text
 ref.child("Experience")/*.child(userID!)*/.observeSingleEvent(of: .value) {(snapshot) in
            if snapshot.hasChild(userID!){
                let value = snapshot.value as? NSDictionary


                let ldg_day = value?["LDG_DAY"] as? String ?? "123"
                let ldg_night = value?["LDG_NIGHT"] as? String ?? "0"
                let apch_ifr = value?["APCH_IFR"] as? String ?? "0"


                self.intLdgDay = Int(ldg_day)!
                self.intLdgNight = Int(ldg_night)!
                self.intApchIfr = Int(apch_ifr)!

                print("string = \(ldg_day) int = \(self.intLdgDay)")



            }
        }
}

Теперь код работает не так, как хотелось бы ... На самом деле мойкод возвращает базовое значение as? String ?? "123", но snapshot.value получает хорошее значение из firebase ... Что не так?Я использую этот код для многих других частей моего приложения, и никаких проблем по этому поводу?

Спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

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

ПРИМЕЧАНИЕ:

Я вижу, что путь для чтения имеет комментарий uidтак что неясно, намеревались ли вы прочитать одного пользователя (оставив в uid) или действительно хотели загрузить каждого пользователя за один раз (тысячи).Этот ответ предполагает, что вы собираетесь читать только этот конкретный пользовательский узел.См. Ответ @Callam, если вы намеревались прочитать ВСЕ пользовательские узлы за один раз.

Теперь у вас есть код, использующий snapshot.hasChild, который просматривает узел, чтобы определить, существует ли дочерний элемент, пользовательский uid,и это не так, поэтому код всегда будет терпеть неудачу.

if snapshot.hasChild(userID!)

Я думаю, что вы хотите использовать snapshot.exists, чтобы убедиться, что это правильный узел перед чтением.Вот код:

let experienceRef = self.ref.child("Experience")
let usersExpRef = experienceRef.child(uid)
usersExpRef.observeSingleEvent(of: .value) { snapshot in
    if snapshot.exists() {
        let value = snapshot.value as! [String: Any]
        let ldg_day = value["LDG_DAY"] as? String ?? "123"
        print("string = \(ldg_day)")
    } else {
        print("the \(uid) node does not exist")
    }
}

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

guard let thisUser = Auth.auth().currentUser else { return }
let uid = thisUser.uid

Примечание Iтакже заменил старый объект NSDictionary на его Swifty-аналог [String: Any]

0 голосов
/ 29 декабря 2018

Предполагая, что ваша структура из корня, а Experience содержит более одного идентификатора пользователя, ваш код в настоящее время наблюдает значение для всех идентификаторов пользователя, поскольку /*.child(userID!)*/ закомментирован.

Поэтому вызапрашивает опыт каждого пользователя и проверяет на клиенте, существует ли текущий пользователь как ребенок - это будет успешно, если идентификатор текущего пользователя присутствует в Experience/$uid.

ref.child("Experience")/*.child(userID!)*/.observeSingleEvent(of: .value) { (snapshot) in
    if snapshot.hasChild(userID!) {
        let value = snapshot.value as? NSDictionary

Теперь у нас есть снимок со всемиОпыт и мы подтвердили, что у него есть дочерний элемент для идентификатора текущего пользователя - нам нужно получить этого дочернего элемента и привести его значение к словарю.

let value = snapshot.childSnapshot(forPath: userID).value as? NSDictionary

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


Так что если выраскомментируйте .child(userID!), снимок будет иметь только один опыт, поэтому snapshot.hasChild(userID!) не удастся.Вместо этого вы можете использовать snapshot.exists() и / или условное приведение, чтобы определить, существует ли моментальный снимок для userID и / или, таким образом, его можно касттировать.

func getUserExp() {
    let ref = Database.database().reference()
    let userID = Auth.auth().currentUser?.uid
    let Date = self.flightDate.text

    ref.child("Experience").child(userID!).observeSingleEvent(of: .value) { snapshot in
        if snapshot.exists() {
            let value = snapshot.value as? [String:String]

            let ldg_day = value?["LDG_DAY"] ?? "123"
            let ldg_night = value?["LDG_NIGHT"] ?? "0"
            let apch_ifr = value?["APCH_IFR"] ?? "0"

            self?.intLdgDay = Int(ldg_day)!
            self?.intLdgNight = Int(ldg_night)!
            self?.intApchIfr = Int(apch_ifr)!

            print("string = \(ldg_day) int = \(self.intLdgDay)")
        } else {
            print("experience for \(snapshot.key) doesn't exist")
        }
    }
}

Вы можете очистить этобит со структурой и расширением.

// Experience.swift

struct Experience {
    var ldg_day: String
    var ldg_night: String
    var apch_ifr: String
}

extension Experience {
    static var currentUserRef: DatabaseReference? {
        return Auth.auth().currentUser.flatMap {
            return Database.database().reference(withPath: "Experience/\($0.uid)")
        }
    }

    init?(snapshot: DataSnapshot) {
        guard snapshot.exists() else { return nil }

        let value = snapshot.value as? [String:String]

        self.ldg_day = value?["LDG_DAY"] ?? "123"
        self.ldg_night = value?["LDG_NIGHT"] ?? "0"
        self.apch_ifr = value?["APCH_IFR"] ?? "0"
    }
}

Et voilà,

func getUserExp() {
    Experience.currentUserRef?.observeSingleEvent(of: .value, with: { [weak self] in
        if let experience = Experience(snapshot: $0) {
            self?.intLdgDay = Int(experience.ldg_day)!
            self?.intLdgNight = Int(experience.ldg_night)!
            self?.intApchIfr = Int(experience.apch_ifr)!

            print("string = \(experience.ldg_day) int = \(self.intLdgDay)")
        } else {
            print("experience for \($0.key) doesn't exist")
        }
    })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...