0

First, this is not a duplicate of What does this mean? "'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X"

I have looked at that question and a couple others, and have made sure that my class is connected through the identity inspector as well as the connections inspector. My class also shows up through the Automatic mode in the assistant editor.

    if let currentUser = FIRAuth.auth()?.currentUser {

        ref = FIRDatabase.database().reference()
        ref.child("Teams").child(self.teamName.text!).setValue(["Name" : self.teamName.text!])
        ref.child("Teams").child(self.teamName.text!).setValue(["Number" : self.teamNumber.text!])
        ref.child("Teams").child(self.teamName.text!).setValue(["Password" : self.teamPassword.text!])
        ref.child("Teams").child(self.teamName.text!).setValue(["memberCount" : 1])
        print("1")

        let userName = "member" + String(1)
        let currentUserEmail = currentUser.uid
        ref.child("Teams").child(self.teamName.text!).child("memberList").setValue([userName : currentUserEmail])
        print("2")

        if let userteamcount = self.ref.child("Users").child(currentUser.uid).value(forKey: "teamCount") as? Int {
            let currentTeam = "team" + String(userteamcount + 1)
            print("4")
            self.ref.child("Users").child(currentUser.uid).setValue(["teamCount" : (userteamcount + 1)])
            print("5")
            self.ref.child("Users").child(currentUser.uid).child("joinedTeams").setValue([currentTeam : self.teamNumber.text!])
            print("6")
        }
    }

An important note is that it prints out 1 and 2 before sending the error.

Also, here's the specfic error that I get:

1
2
Terminating app due to uncaught exception 'NSUnknownKeyException',    reason: 
'[<FIRDatabaseReference 0x618000054160> valueForUndefinedKey:]: 
this class is not key value coding-compliant for the key teamCount.'

Thanks so much.

Community
  • 1
  • 1
  • 1
    `child(currentUser.uid).value(forKey: "teamCount")` crashes because you are assuming that this `child` has a `teamCount` property and it doesn't. – matt Mar 09 '17 at 19:40

1 Answers1

2
self.ref.child("Users").child(currentUser.uid).value(forKey: "teamCount") as? Int

You can't get a value from the DB like that. You need to observe the reference to get a value. But it seems like you're trying to increment a value, so you should be using a transaction to do that anyway. Because if you don't, when two users try to increment it at the same time, there's a good chance one's changes would overwrite the other (personally, I find it more readable as well). Here's how.

self.ref.child("Users").child(currentUser.uid).child("teamCount").runTransactionBlock({ (currentData: FIRMutableData) -> FIRTransactionResult in
  var teamCount = currentData.value as? Int
  if teamCount != nil {
    currentData.value = teamCount + 1
  }
  return FIRTransactionResult.success(withValue: currentData)
}) { (error, committed, snapshot) in
     if error == nil {
       // Update joinedTeams here
       let value = snapshot.value as? Int
       let currentTeam = "team\(value)"
       self.ref.child("Users").child(currentUser.uid).child("joinedTeams").child(currentTeam).setValue(self.teamNumber.text!)
     }
}

Here's how you would normally load teamCount from your DB, without the transaction.

self.ref.child("Users").child(currentUser.uid).child("teamCount").observeSingleEvent(.value, with: { dataSnapshot in
  let teamCount = dataSnapshot.value as? Int
})

I haven't tested the code, but I think it should work.

Links:

Firebase Transactions