Reputation: 1593
I'm using Parse.com as the backend for my app. In the backend I have the following classes:
User (objectId, name, username, password, etc)
Team (objectId, teamName, etc)
User_To_Team (objectId, teamId, userId)
The "teamId" and "userId" columns are pointers to the User and the Team classes.
I'm trying to query Parse in a way that will show me all of the Teams the user is associated with. I have tried the following, which doesn't work.
var innerQuery = PFQuery(className: "User_To_Team")
innerQuery.whereKey("userId", equalTo: PFUser.currentUser())
var query = PFQuery(className:"Team")
query.whereKey("objectId", matchesQuery:innerQuery)
query.findObjectsInBackgroundWithBlock {
...
}
I've the documentation, but they don't provide many examples.
I'm getting the following error:
[Error]: bad type for $inQuery (Code: 102, Version: 1.6.1) Error: Error Domain=Parse Code=102 "The operation couldn’t be completed. (Parse error 102.)" UserInfo=0x1702779c0 {error=bad type for $inQuery, code=102}, [error: bad type for $inQuery, code: 102]
---EDIT---
I'm now trying the following, which no longer generates an error, but doesn't generate any results either. I also changed the "Team" to "Squad", as teams will be referred to as Squads in the app. Just cleaner for me.
var innerQuery = PFQuery(className: "User_To_Squad")
innerQuery.whereKey("userId", equalTo: PFUser.currentUser())
var query = PFQuery(className:"Squad")
query.whereKey("objectId", matchesKey: "squadId", inQuery: innerQuery)
Upvotes: 1
Views: 1830
Reputation: 175
For others that have this problem and don't want to change their data model or queries here is what I found.
The problem was that the Class was not created on Parse's servers. Doing a nested query on a class that does not exist yet causes the type error. All you need to do to fix it is create the class along with the columns that are going to be queried.
For my use case, the ParseFollower class was not created on Parse server's yet, that caused me to get the bad type for inQuery error.
let fromQuery = ParseUserInfo.query()
fromQuery?.includeKey("username")
fromQuery?.whereKey("username", equalTo:myUsername)
let fromFollowerQuery = ParseFollower.query()
fromFollowerQuery?.includeKey("to")
fromFollowerQuery?.includeKey("from")
fromFollowerQuery?.whereKey("from", matchesQuery: fromQuery!)
I did not change this code at all, I just created the class on the server and the issue went away. Hope this helps someone else.
Upvotes: 1
Reputation: 1593
I ended up getting this solved by simply using the "includeKey" method in Parse.
My query now looks like this:
var query = PFQuery(className: "User_To_Squad")
query.includeKey("squadId")
query.whereKey("userId", equalTo: PFUser.currentUser())
query.findObjectsInBackgroundWithBlock {
...
}
The "includeKey" method returns relational classes as an object. As my user and squad columns in User_To_Squad class are both pointers, this worked extremely well and is done in one query.
Parse Query Documentation covers this decently.
Upvotes: 1
Reputation: 3758
Alternatively, you could change your data model by following this blog post: http://blog.parse.com/2012/03/28/parse-supports-many-to-many-relations/
Parse can handle many-to-many relationships (like players and teams). Basically, you just need to save an array of PFObject
representing your users into your team PFObject
.
var team = PFObject(className: "Team")
team.setObject(p, forKey: "players") // here, p is an array containing PFObject corresponding to the User class
team.setObject("Ferrari", forKey: "teamName")
// ...
team.saveInBackground()
After that, you should be able to query with a single statement:
var query = PFQuery(className: "Team")
query.whereKey("players", equalTo: PFUser.currentUser())
Upvotes: 0