Firebase with Swift 3 counting the number of children

前端 未结 3 830
遥遥无期
遥遥无期 2020-12-10 09:02

I have an array of strings and I am trying to populate it through firebase. It is a chat application and when a user creates a room he or she names the room. When the user l

相关标签:
3条回答
  • 2020-12-10 09:25

    Firebase data is loaded (and synchronized) asynchronously. This is easiest to see if you add some debug logging:

    let ref = firebase.child("users").child(fUID).child("participating")
    
    print("Starting observing");
    ref.observe(.value, with: { (snapshot: FIRDataSnapshot!) in
        print("Got snapshot");
        print(snapshot.childrenCount)
        rooms.count = snapshot.childrenCount
    })
    
    print("Returning count");
    return rooms.count
    

    When you run this snippet, the logging output will be:

    Start observing

    Returning count

    Got snapshot

    This is probably not the order you expected the output to be in. And it also explains why your count will never be correct: the data hasn't been loaded yet, so it can't be counted.

    This is the reason why Firebase listeners work with callback blocks: the block is invoked when the data is synchronized.

    0 讨论(0)
  • 2020-12-10 09:29

    I guess that "rooms" is an array of class Room.

    "an error that count is a get only property" happen when you try to set the range of array "rooms" - You can't do that.

    'count' properties is read-only access. In person language, It be like. You have a bag. You put a apple to the bag. You put another apple to the bag. Now you have 2 apple. You can't only say "My bag have 2 apples."

    To fix it:

    • You have to create variable with type 'Room' class for each snapshot : FIRDataSnapshot
    • Add it to rooms.

    Example:

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    let ref = firebase.child("users").child(fUID).child("participating")
    
    ref.observe(.value, with: { (snapshot: FIRDataSnapshot!) in
        print(snapshot.childrenCount)
    
        let room = Room()
        // Use you snapshot(FIRDataSnapshot) to create the data of the room.
        rooms.append(room)
    })
    
    return rooms.count
    

    }

    0 讨论(0)
  • 2020-12-10 09:41

    My way is to have the closure. When the call has completed then it will return the number of children

    typealias countAllPostsResult = (UInt) -> Void
    class func countAllPosts(isDeleted: Bool,completedHandler: @escaping countAllPostsResult) {
        print("countAllPosts ...is running...", isDeleted)
        var dataSnapshot = [DataSnapshot]()
    
        Constants.Commons.posts_node_ref.queryOrdered(byChild: Constants.Posts.is_deleted).queryStarting(atValue: "false").queryEnding(atValue: "false\u{f8ff}").observeSingleEvent(of: .value, with: { (snapshot) -> Void in
    
            for snap in snapshot.children {
                dataSnapshot.append(snap as! DataSnapshot)
            }
            if dataSnapshot.count > 0 {
                completedHandler(UInt(dataSnapshot.count))
            } else {
                completedHandler(0)
            }
        })
    
    }
    
    0 讨论(0)
提交回复
热议问题