简体   繁体   English

Firebase-for循环Swift内部嵌套的observeSingleEvent方法

[英]Firebase - nested observeSingleEvent methods inside for loop Swift

I have been trying to fetch data from Firebase using Realtime database. 我一直在尝试使用实时数据库从Firebase提取数据。 I want to check the contacts in iPhone and then if any contact number matches with that of any number in "numbers" table in db, then I have to get the user_key from it and then using that key, I have to obtain the corresponding details from users table. 我想检查iPhone中的联系人,然后如果任何联系人号码与db中“数字”表中的任何号码匹配,那么我必须从中获取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 is the array of contact numbers for a particular contact. 数字是特定联系人的联系人号码数组。 For a contact having single number, this works fine. 对于具有单个号码的联系人,此方法很好。 But for contacts having multiple numbers, the 但是对于具有多个号码的联系人,

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

will call after some time due to which the next index in the for loop gets called. 会在一段时间后调用,由于调用了for循环中的下一个索引。 So even if I have the data in first number in a contact, it will return failure because the next number will be iterated before the success of the observeSingleEvent. 因此,即使我的联系人的第一个数字中有数据,它也会返回失败,因为下一个数字将在observeSingleEvent成功之前进行迭代。

I have been sitting for hours now, no ideas left with me. 我已经坐了几个小时了,没什么主意。 Please help! 请帮忙!

I think a better approach is: 我认为更好的方法是:
1 - Get all numbers from DB. 1-从数据库获取所有数字。
2 - Get all contact numbers that exists on DB. 2-获取数据库上存在的所有联系电话。
3 - Finally, get the name of that contacts.(Exactly the way you are doing). 3-最后,获取联系人的姓名。(完全按照您的操作方式)。
OBS: To do that you must change your DB. OBS:为此,您必须更改数据库。 Your numbers must be saved as key-value pair. 您的数字必须另存为键值对。 For exemple "555-0000" : true. 例如“ 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 ....
                        }
                    })
            }
        }
    })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM