Swift не получает значения Firebase (возвращает значения как NSNull) - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь извлечь значения из моей базы данных в реальном времени Firebase, но по какой-то причине значения возвращаются как NSNull.Я получаю сообщение об ошибке «Не удалось привести значение типа« NSNull »к« NSNumber »в строке 13, пока я не изменил« let count = ... »на« if let ».Я не уверен, почему эти значения возвращают NULL, когда они не.

Я уже пытался напечатать полученный снимок, и, как я ожидал, ни одно из значений не является NULL.Я в тупике.Вот журнал, который я получаю при печати полученного снимка:

[Snap (A12-1A) 0, Snap (B1-2A) 0, Snap (C2-3A) 0, Snap (D3-4A) 0, Snap (E4-5A) 0, Snap (F5-6A) 0, Snap (G6-7A) 0, Snap (H7-8A) 0, Snap (I8-9A) 0, Snap (J9-10A) 5, Snap (K10-11A) 0, Snap (L11-12P) 0, Snap (M12-1P) 0, Snap (N1-2P) 0, Snap (O2-3P) 0, Snap (P3-4P) 0, Snap (Q4-5P) 0, Snap (R5-6P) 0, Snap (S6-7P) 0, Snap (T7-8P) 0, Snap (U8-9P) 0, Snap (V9-10P) 0, Snap (W10-11P) 0, Snap (X11-12A) 0]

Все данные в этом снимке - это данные в моей базе данных Firebase, поэтому я не уверен, почему я получаю эту ошибку.

Моя настройка Firebase: регистрация по календарю --- 04132019 --- (A12-1A: 0, B1-2A: 0, ..., X11-12P: 0)

func getCalendarSignupsOnDate(selectedDate: String, handler: @escaping (_ dateSignups: [Calendar]) -> ()) {
        var calendarArray = [Calendar]()

        REF_CALENDAR_SIGNUPS.observeSingleEvent(of: .value) { (snapshot) in
            guard let snapshot = snapshot.children.allObjects as? [DataSnapshot] else { return }

            var doesContainDate = false
            for date in snapshot {
                if date.key == selectedDate {
                    doesContainDate = true

                    self.REF_CALENDAR_SIGNUPS.child(date.key).observeSingleEvent(of: .value, with: { (dateSnapshot) in
                        guard let dateSnapshot = dateSnapshot.children.allObjects as? [DataSnapshot] else { return }

                        for timeSlots in dateSnapshot {
                            let time = timeSlots.key
                            if let count = timeSlots.childSnapshot(forPath: "J9-10A").value as? Int {
                                let calendarData = Calendar(time: time, signupCount: count)
                                calendarArray.append(calendarData)
                                handler(calendarArray)
                            } else {
                                let count = 0
                                let calendarData = Calendar(time: time, signupCount: count)
                                calendarArray.append(calendarData)
                                handler(calendarArray)
                            }
                        }
                    })
                }
            }
            for item in calendarArray {
                print(item.time + " " + String(item.signupCount))
            }
            if doesContainDate == false {
                let dateSignUpData = [
                    "A12-1A": 0,
                    "B1-2A": 0,
                    "C2-3A": 0,
                    "D3-4A": 0,
                    "E4-5A": 0,
                    "F5-6A": 0,
                    "G6-7A": 0,
                    "H7-8A": 0,
                    "I8-9A": 0,
                    "J9-10A": 0,
                    "K10-11A": 0,
                    "L11-12P": 0,
                    "M12-1P": 0,
                    "N1-2P": 0,
                    "O2-3P": 0,
                    "P3-4P": 0,
                    "Q4-5P": 0,
                    "R5-6P": 0,
                    "S6-7P": 0,
                    "T7-8P": 0,
                    "U8-9P": 0,
                    "V9-10P": 0,
                    "W10-11P": 0,
                    "X11-12A": 0
                    ]
                    as [String : Int]

                self.REF_CALENDAR_SIGNUPS.child(selectedDate).updateChildValues(dateSignUpData)

                for timeSlots in dateSignUpData {
                    let time = timeSlots.key
                    let count = timeSlots.value
                    let calendarData = Calendar(time: time, signupCount: count)
                    calendarArray.append(calendarData)
                }
            }

            handler(calendarArray)
        }
    }

1 Ответ

0 голосов
/ 14 апреля 2019

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

Вашей функции передана одна выбранная дата

func getCalendarSignupsOnDate(selectedDate: String

, что означает, что вы знаете узел даты, который вы пытаетесь прочитать. Однако код читает во ВСЕХ датах и ​​перебирает их, пытаясь найти эту дату

 for date in snapshot {
   if date.key == selectedDate {

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

Кроме того, далее в коде вы перебираете дочерние узлы A12-1A, B1-2A, ища конкретный узел

if let count = timeSlots.childSnapshot(forPath: "J9-10A").value as? Int

, который вообще не будет работать, поскольку временные интервалы A12-1A и т. Д. Имеют значения, все 0, а не дочерние снимки. Код продолжает и появляется, что вы хотите прочитать значение этого конкретного дочернего узла, а затем установить остальные 0, которые добавляются в ваш массив календаря.

let count = 0
let calendarData = Calendar(time: time, signupCount: count)

Но затем, если вы не найдете этот временной интервал, все дочерние узлы все равно будут установлены в 0.

if doesContainDate == false {
    let dateSignUpData = [
       "A12-1A": 0,
       "B1-2A": 0,

Итак ... я думаю, что я понял суть того, что вы пытаетесь сделать. Вот некоторый код, который может привести вас в правильном направлении. Это должно заменить весь код в вашем вопросе.

func getCalendarSignupsOnDate(selectedDate: String) {
    var dateSignUpData = [
        "A12-1A": 0,
        "B1-2A": 0,
        "C2-3A": 0,
        "J9-10A": 0
    ]
    let slotYourLookingFor = "J9-10A"
    let dateRef = self.REF_CALENDAR_SIGNUPS.child(selectedDate).child(slotYourLookingFor)
    dateRef.observeSingleEvent(of: .value, with: { snapshot in
        if snapshot.exists() {
            let count = snapshot.value as? Int ?? 0
            dateSignUpData[slotYourLookingFor] = count //update this array element with the new count from Firebaes
        } else { //didn't find the child node at all, will create the date node and add child nodes with val = 0
            self.REF_CALENDAR_SIGNUPS.child(selectedDate).updateChildValues(dateSignUpData)
        }
        //do something with the dateSignUpData array
    })
}

Пояснение:

Укажите дату, которая вас интересует. Код будет читать этот узел с дочерним узлом "J9-10A", который вы ищете.

Если он существует, он будет считывать эти данные и обновлять массив dateSignUpData со счетчиком из этого дочернего узла. Затем вы можете продолжить обработку обновленного массива.

Если узел "J9-10A" не существует, будет создан узел с переданной датой, а затем все слоты дочерних узлов будут установлены в 0. Затем вы можете обработать массив дальше.

Последнее. Вероятно, хорошая идея хранить даты как ггггммдд для заказа.

...