ios - 在 Firebase 上查询多个键

标签 ios swift firebase firebase-realtime-database

我正在遵循 Firebase 的扁平化数据建议,但我无法从我的数据库中列出一系列项目。

这是我的数据库文件的示例:

"users" : {
    "UID12349USER" : {
      "firstName" : "Jon",
      "lastName" : "Snow",
      "email" : "jonsnow@winterfell.com",
      "albums" : {
        "UID124ALBUM" : true,
        "UID125ALBUM" : true
      }
    }
},
"albums" : {
    "UID124ALBUM" : {
      "name" : "My Artwork",
    },
    "UID125ALBUM" : {
      "name" : "My Sketches",
    }
}

我正在检索给定用户的相册列表:

let userAlbums = database.child(usersKey).child(user.uid).child(albumsKey)
userAlbums.observeSingleEventOfType(.Value, withBlock: { snapshot in
    // fetch [UID124ALBUM: 1, UID125ALBUM: 1]
})

现在我希望我可以在一次查询中检索所有用户的相册。 我可以做一批查询,并填充一个异步数组,但这对我来说似乎不是一个好方法......

for key in albumKeys {
    let album = database.child(self.albumsKey).child(key)
    album.observeSingleEventOfType(.Value, withBlock: { snapshot in
        // fetch album.. append to array
    })
}

由于请求的异步性质,使用这种方法很难检测查询何时完成。此外,由于连接不良,某些请求可能会失败。

此外,如果我想过滤其中一个具有给定名称(例如“我的作品”)的相册,或者如果它不存在则返回 nil,我也会遇到一个棘手的结束条件。

var found = false

for key in albumKeys {
    let album = database.child(self.albumsKey).child(key)
    album.observeSingleEventOfType(.Value, withBlock: { snapshot in
        // if current.name == "My Artwork"
        // completion(current)
    })
}
// This block will be called before observeSingleEventOfType =.=
if !found {
    completion(nil)
}

我在 iOS 和 Swift 方面有很好的背景,但我知道 Firebase 和 NoSQL 数据库。有人能给我指出一个好的方向吗?我应该放弃 Firebase 并尝试其他方法吗?我是否缺少一些可以查询我需要的方法?我的 json 结构是否错误并且缺少一些额外的键?

谢谢

最佳答案

我建议使用 DispatchGroup 和互斥来处理 for 循环中的异步函数。以下是您随 DispatchGroup 一起提供的代码,以确保在检查 if 语句之前循环中的所有异步函数都已完成:

let myGroup = DispatchGroup()
var found = false
// iterate through your array
for key in albumKeys {
    let album = database.child(self.albumsKey).child(key)
    // lock the group 
    myGroup.enter()
    album.observeSingleEventOfType(.Value, withBlock: { snapshot in
        if current.name == "My Artwork" {
             found = true
        }
        // after the async work has been completed, unlock the group
        myGroup.leave()
    })
}
// This block will be called after the final myGroup.leave() of the looped async functions complete
myGroup.notify(queue: .main) {
    if !found {
        completion(nil)
    }
}

myGroup.notify(queue: .main) { 代码块中包含的任何内容在 myGroup.enter()myGroup.leave() 之前不会执行 被调用的次数相同。请务必在 Firebase 观察 block 内调用 myGroup.leave()(在异步工作之后),并确保即使观察产生错误也会调用它。

关于ios - 在 Firebase 上查询多个键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37716350/

相关文章:

ios - 邀请他们使用我的应用程序后,是否可以获取 Facebook 好友的 Facebook Id?

swift - 检查 Swift 中的密码字符串强度标准

ios - 字符串没有在 ios Swift 中正确转换为日期

android - 如何在不验证(登录/注册)用户的情况下保护 Firebase 实时数据库?

javascript - 使用 onDisconnect() 拒绝 Firestore/Firebase 权限

iphone - 为什么 iPhone 启动图像在转换时不与主屏幕背景图像对齐?

ios - View Controller 底部的额外空间?

ios - UIViewController 内的 UITableView 不显示

ios - Swift - 将字典数组保存到 NSUserDefaults

node.js - 如何处理来自分布式系统的两个http请求?