【问题标题】:Retrieving an array of children in Firebase using Swift使用 Swift 在 Firebase 中检索一组子项
【发布时间】:2016-04-27 06:04:25
【问题描述】:

我有一个看起来像这样的数据库:

火力基地
餐厅
麦当劳
菜单项 1:汉堡
菜单项 2:薯条
菜单项 3:饮料
肯德基
菜单项 1:鸡肉
菜单项 2:土豆泥
菜单项 3:饮料
塔可钟
菜单项 1:炸玉米饼
菜单项 2:墨西哥卷饼
菜单项 3:饮料

如何检索仅包含餐厅名称的列表(数组或字典都可以),而没有它们各自的菜单项?

理想情况下,输出应该类似于 ["McDonalds", "KFC", "Taco Bell"],带有可访问的索引或键。

【问题讨论】:

  • 有答案,但最重要的答案是,你不能。 Firebase 始终返回键:值对。您将遇到 Firebase 数据结构的问题 - 请参阅我的替代答案。

标签: ios xcode swift firebase children


【解决方案1】:

你可以这样做:

var ref = Firebase(url: "https://<yourApp>.firebaseio.com/restaurants/")

ref.observeEventType(.Value, withBlock: {
    snapshot in
    var restaurantNames = [String]()
    for restaurant in snapshot.children {
        restaurantNames.append(restaurant.key)
    }
    print(restaurantNames)
})

restaurantNames 将包含您要求的数组。您仍在从 firebase 接收完整的餐厅对象,但只是使用它们的键(名称)。

【讨论】:

  • 刚刚添加了它,它完美地完成了我需要它做的事情,谢谢!
【解决方案2】:

答案是,您不能只返回键。由于文本数据和节点名称之间的联系过多,您的问题中的结构可能会带来一些挑战。

这是一个可选结构,可将所有内容分开以便于查询。

restaurants
   restaurant_id_0
     restaurant_ref: restaurant_name_0
     menu:
       menu_id_0:
          name: Burger
       menu_id_1
          name: Fries
       menu_id_2
          name: Beer!
   restaurant_id_1
     restaurant_ref: restaurant_name_1
     menu
       menu_id_0:
          name: Roast Beef Classic
       menu_id_1
          name: Curly Fries
       menu_id_2
          name: Milkshake

然后是名字

restaurant_names
   restaurant_name_0: McDonalds
   restaurant_name_1: Arby's

使用这种结构,您可以将字符串数据与保存数据的节点分开,这使您可以轻松地从restaurent_name 节点查询所有餐厅名称。您还可以查询哪些餐厅的菜单上有汉堡。甚至可以找到提供奶昔的。

我什至可能会建议打破菜单以进一步扁平化数据。

menus
   restaurent_id_0
     menu_id_0:
        name: Burger
     menu_id_1
        name: Fries
     menu_id_2
        name: Beer!

这两种方法都可以,这种结构的好处之一是,如果 Arby 决定用 Roast Beef Max(哦,是的!)替换 Roast Beef Classic(哦,不!),您可以只更改名称组件而不会影响其他数据

/restaurant_id_1/menu/menu_id_0/name = "Roast Beef Max"

【讨论】:

  • @JoeSloan 试试这个结构 - 这是 Firebase 的常见设计模式。如果有帮助,请采纳我的回答!
  • 嗨,Jay,您能解释一下您的答案与 Eirik Berntsen 下面的答案之间的区别吗?我能够使用他的答案获得所需的数组,但是按照您建议的方式实际重构数据库可能有优势?
  • @JoeSloan 当然! Erik 提供了一个很好的答案。但是,通过 .value 观察会返回节点中的所有内容……所有内容。因此,如果有 1000 家餐厅并且他们的菜单上有 25 个项目,并且假设您在每个节点中存储了一些其他数据,那么将返回 1000 * 25 节点和子节点(如果有其他数据,则返回子节点的子节点)。这可能是要处理的很多数据。通过Denormalizing your data,您正在使用较浅结构中的较小块。使用 Firebase,越扁平越好。
  • @JoeSloan 哦,还有其他一些东西:您不能更改键,但可以更改值。使用静态文本(在这种情况下为餐厅名称)来命名您的键通常不是一个好主意;如果名字变了怎么办?如果它存储为一个值,那么您可以使用 ref.setValue("new name") 轻松更改它。和查询......对键的查询很奇怪,但对值的查询很容易。最重要的是,通常最好将静态键与变量数据分离。
  • 太棒了,感谢杰,这确实有道理。感谢您的资源!
【解决方案3】:

我自己是这方面的新手,虽然整个火力基地的东西都很棒,但教程对我来说有点含糊。恐龙拉拉等无论如何,在花了很长时间摆弄数组来填充表格视图之后,我开始明白了。或者可能不是?不知道。但是可以肯定的是,您可以通过观察事件类型 childAdded 来获取键,然后通过 snapshot.value 来获取键,这为您提供了迭代的整个 malark 和 snapshot.key,它一次为您提供一个单独的键: var boink = 快照.key MyboinkArray.append(boink)

【解决方案4】:

您可以通过以下方法完成此操作:-

func getDataSource()
{    
    let macdArray = ["Menu Item 1" : "burger","Menu Item 2" : "fries","Menu Item 3" : "drink"]
    let macdDict = ["McDonalds":macdArray]
    let kfcArray = ["Menu Item 1" : "chicken","Menu Item 2" : "mashed potatoes","Menu Item 3" : "drink"]
    let kfcDict = ["KFC":kfcArray]
    let tacobellDArray = ["Menu Item 1" : "taco","Menu Item 2" : "burrito","Menu Item 3" : "drink"]
    let tacobellDict = ["Taco Bell":tacobellDArray]
    let restaurentArray = [macdDict,kfcDict,tacobellDict] as NSMutableArray
    let restaurentDict = ["restaurants":restaurentArray]

    let parentDict = ["Firebase":restaurentDict] as NSDictionary

    print(parentDict.objectForKey("Firebase")?.objectForKey("restaurants"))

    let consolidatedArray = NSMutableArray()

    for var i = 0; i < restaurentArray.count; i++ {
        consolidatedArray.addObject(restaurentArray.objectAtIndex(i).allKeys)
    }

    print(consolidatedArray)
}

我已将您的数据用作静态数据,您只需替换从后端接收的数据。

希望这对你有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 2016-08-12
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 2019-07-18
    • 2017-05-29
    相关资源
    最近更新 更多