【问题标题】:Firebase - nested observeSingleEvent methods inside for loop SwiftFirebase - for loop Swift 内嵌套的 observeSingleEvent 方法
【发布时间】:2018-10-12 13:02:54
【问题描述】:

我一直在尝试使用实时数据库从 Firebase 获取数据。我想检查 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 是特定联系人的联系人号码数组。对于具有单个号码的联系人,这可以正常工作。但是对于有多个号码的联系人,

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

将在一段时间后调用,因为 for 循环中的下一个索引被调用。所以即使我在一个联系人的第一个号码中有数据,它也会返回失败,因为下一个号码将在observeSingleEvent成功之前迭代。

我已经坐了几个小时了,没有留下任何想法。请帮忙!

【问题讨论】:

  • 你找到解决这个问题的方法了吗?我也面临同样的问题。

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

我认为更好的方法是:
1 - 从 DB 中获取所有数字。
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 ....
                        }
                    })
            }
        }
    })

【讨论】:

  • 抱歉耽搁了,您所说的第 1 步和第 2 步是什么意思? “1 - 从 DB 中获取所有数字。” 2 - 获取数据库中存在的所有联系电话。”。我认为这没有区别。@Bergmpe
  • 第 1 步:从“数字”表中获取所有数字。步骤2:由以下代码执行:let numbersMatchedOnDB = numbersFromDB.keys.filter{ numbers.contains($0) } 这里我们通过联系号码过滤“号码”表中的号码。结果是与“numbers”表中的某个号码匹配的联系人号码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 2015-10-18
  • 2019-06-25
  • 2018-06-13
  • 1970-01-01
相关资源
最近更新 更多