Iterate over snapshot children in Firebase

吃可爱长大的小学妹 提交于 2019-11-26 13:02:29

If I read the documentation right, this is what you want:

var ref = Firebase(url: MY_FIREBASE_URL)
ref.observeSingleEvent(of: .value) { snapshot in
    print(snapshot.childrenCount) // I got the expected number of items
    for rest in snapshot.children.allObjects as! [FIRDataSnapshot] {
       print(rest.value)     
    }
}

A better way might be:

var ref = Firebase(url: MY_FIREBASE_URL)
ref.observeSingleEvent(of: .value) { snapshot in
    print(snapshot.childrenCount) // I got the expected number of items
    let enumerator = snapshot.children
    while let rest = enumerator.nextObject() as? FIRDataSnapshot {
       print(rest.value)     
    }
}

The first method requires the NSEnumerator to return an array of all of the objects which can then be enumerated in the usual way. The second method gets the objects one at a time from the NSEnumerator and is likely more efficient.

In either case, the objects being enumerated are FIRDataSnapshot objects, so you need the casts so that you can access the value property.


Using for-in loop:

Since writing the original answer back in Swift 1.2 days, the language has evolved. It is now possible to use a for in loop which works directly with enumerators along with case let to assign the type:

var ref = Firebase(url: MY_FIREBASE_URL)
ref.observeSingleEvent(of: .value) { snapshot in
    print(snapshot.childrenCount) // I got the expected number of items
    for case let rest as FIRDataSnapshot in snapshot.children {
       print(rest.value)     
    }
}
Ketan P

I have just converted the above answer to Swift 3:

ref = FIRDatabase.database().reference()    
ref.observeSingleEvent(of: .value, with: { snapshot in
       print(snapshot.childrenCount) // I got the expected number of items
       for rest in snapshot.children.allObjects as! [FIRDataSnapshot] {
           print(rest.value)
           }
})

A better way might be:

    ref = FIRDatabase.database().reference() 
    ref.observeSingleEvent(of: .value, with: { snapshot in
            print(snapshot.childrenCount) // I got the expected number of items
            let enumerator = snapshot.children
            while let rest = enumerator.nextObject() as? FIRDataSnapshot {
                print(rest.value)
            }
        })
Dan

This is pretty readable and works fine:

var ref = Firebase(url:MY_FIREBASE_URL)
ref.childByAppendingPath("some-child").observeSingleEventOfType(
  FEventType.Value, withBlock: { (snapshot) -> Void in

      for child in snapshot.children {

        let childSnapshot = snapshot.childSnapshotForPath(child.key)
        let someValue = childSnapshot.value["key"] as! String
      }
})
   ref = FIRDatabase.database().reference().child("exampleUsernames")    
   ref.observeSingleEvent(of: .value, with: { snapshot in

       for rest in snapshot.children.allObjects as! [FIRDataSnapshot] {

           guard let restDict = rest.value as? [String: Any] else { continue }
           let username = restDict["username"] as? String
       }
   })

Firebase 4.0.1

       Database.database().reference().child("key").observe(.value) { snapshot in
            if let datas = snapshot.children.allObjects as? [DataSnapshot] {
                let results = datas.flatMap({
                  ($0.value as! [String: Any])["xxx"]
                }
                print(results)
            }
       }

If you have multiple keys/values, and want to return an array with dictionary elements, declare an array:

var yourArray = [[String: Any]]()

then change block body to this:

     let children = snapshot.children
     while let rest = children.nextObject() as? DataSnapshot, let value = rest.value {
          self.yourArray.append(value as! [String: Any])
      }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!