Firebase - вложенные методы applySingleEvent внутри для цикла Swift - PullRequest
0 голосов
/ 02 мая 2018

Я пытался получить данные из Firebase, используя базу данных в реальном времени. Я хочу проверить контакты в iPhone, а затем, если какой-либо контактный номер совпадает с номером любого из номеров в таблице «numbers» в БД, я должен получить из него user_key, а затем, используя этот ключ, получить соответствующие данные. из таблицы пользователей.

for number in numbers {
    Database.database().reference().child("numbers/\(number)").observeSingleEvent(of: .value, with: { (snapshot) in
        if snapshot.exists() {
            let userKey = snapshot.value as! String

            // We found this user, no determine there name, (TODO has_image?)
            Database.database().reference().child("users/\(userKey)/public/name").observeSingleEvent(of: .value, with: { (namesnapshot) in
                if namesnapshot.exists() {
                    let name = namesnapshot.value as! String
                    print("FOUND \(name)")
                    complete(.success((userID: userKey, name: name)))
                }
            })

        } else {
            if numbers.index(of: number) == numbers.count - 1 {  // Last Number checked and not found yet, so fail
                complete(.failure(UserApiError.UserNotFound))
            }
        }
    })
}

numbers - это массив контактных номеров для конкретного контакта. Для контакта с одним номером это работает нормально. Но для контактов, имеющих несколько номеров,

Database.database().reference().child("users/\(userKey)/public/name").observeSingleEvent(of: .value, with: { (namesnapshot) in

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

Я сижу уже часами, идей у ​​меня не осталось. Пожалуйста, помогите!

1 Ответ

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

Я думаю, что лучший подход:
1 - Получить все номера из БД.
2 - Получить все контактные телефоны, которые существуют в БД.
3 - Наконец, получите имя этих контактов. (Именно так, как вы делаете).
OBS: Для этого вы должны изменить свою базу данных. Ваши номера должны быть сохранены как пара ключ-значение. Для примера "555-0000": верно.

Database.database().reference().child("numbers").observeSingleEvent(of: .value, with: { (snapshot) in
        guard let numbersFromDB = snapshot.value as? [String: Any] else{
            print("Fail get numbers from db")
        }
        let numbersMatchedOnDB = numbersFromDB.keys.filter{ numbers.contains($0) }//get numbers from contact that exist on DB.
        if numbersMatchedOnDB.isEmpty{
            complete(.failure(UserApiError.UserNotFound))
        }
        else{
            //For each contact number that exist on DB. it gets its name.
            numbersMatchedOnDB.forEach{ numberMatchedOnDB in
                Database.database().reference().child("numbers/\(numberMatchedOnDB)").observeSingleEvent(of: .value, with: { (snapshot) in
                        if snapshot.exists() {
                            let userKey = snapshot.value as! String
                            // .... nothing changed here ....
                        }
                    })
            }
        }
    })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...