1

I have now a observe handle that will check when new channels are added. I want it to be a observeSingleEvent with a button which will reload the channels when the user clicks on it. The observeSingleEvent is working correctly. This is the code:

private func observeChannels() {
    channelRefHandle = channelRef.observe(.childAdded, with: { (snapshot) -> Void in
        self.playersInChannnel.append("\(snapshot.childrenCount)")
        let channelData = snapshot.value as! Dictionary<String, AnyObject>
        let id = snapshot.key
        if let name = channelData["name"] as! String!, name.characters.count > 0 {
            self.channels.append(Channel(id: id, name: name))
            self.tableView.reloadData()
        } else {
            print("Error! Could not decode channel data")
        }
    })
}

I now tried converting it to observeSingleEvent, put the print is saying Error, could not decode channel data. This is my code:

func reloadChannels()
{
    channelRef.observeSingleEvent(of: .value, with: { (snapshot) -> Void in
        self.playersInChannnel.append("\(snapshot.childrenCount)")
        let channelData = snapshot.value as! Dictionary<String, AnyObject>
        let id = snapshot.key
        if let name = channelData["name"] as! String!, name.characters.count > 0 {
            self.channels.append(Channel(id: id, name: name))
            self.tableView.reloadData()
        } else {
            print("Error! Could not decode channel data")
        }
    })
}

What is wrong with this code? This is a print of the snapshot from observeSingleEvent:

Snap (channels) {
    "-Ke3g8tLH9A-_iTVjQhq" =     {
        "-Ke3g8tO2XPCbyIjP4Op" =         {
            PictureVersion = "";
            userID = keVlTMUXyRViUsTVjTnKdvZs7mg1;
            username = pietje;
        };
        name = test;
    };
    "-Ke3gFbijlcQGuJXe42L" =     {
        "-Ke3gFbjsEgpA3wjM1Jv" =         {
            PictureVersion = "";
            userID = keVlTMUXyRViUsTVjTnKdvZs7mg1;
            username = pietje;
        };
        name = test2;
    };
}
Error! Could not decode channel data

Again, firing observeChannels() is showing no errors. Thank you.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Petravd1994
  • 893
  • 1
  • 8
  • 24

1 Answers1

2

You didn't just change from observe to observeSingleEvent, you also switched from observing .childAdded to observing .value. And since you're now listening for a .value, that means that the snapshot you get contains all the child nodes at once (even if there's only one matching child).

For this reason, you will need to loop over the children of the snapshot, to get the channel data you had before:

func reloadChannels()
{
    channelRef.observeSingleEvent(of: .value, with: { (snapshot) -> Void in
        self.playersInChannnel.append("\(snapshot.childrenCount)")
        for channelSnap in snapshot.children {
            let channelData = (channelSnap as! FIRDataSnapshot).value as! Dictionary<String, AnyObject>
            let id = (channelSnap as! FIRDataSnapshot).key

            if let name = channelData["name"] as! String!, name.characters.count > 0 {
                self.channels.append(Channel(id: id, name: name))
                self.tableView.reloadData()
            } else {
                print("Error! Could not decode channel data")
            }
        }
    })
}

See the answers to this question for more on how to loop over the children of a snapshot: Iterate over snapshot children in Swift (Firebase)

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807