1

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)

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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())

4 Comments

Interesting. Is there a benefit to going with many-to-many over the relational style I have in place?
Well, I'd say: it depends on what you're trying to do. Your current model follows traditional SQL-style data modeling, while the one I'm suggesting is more headed towards NoSQL approaches. Both have advantages. More generally, the NoSQL-way might be better if you know all your use cases very well. There might be some cases later in your app where you would need, for efficiency reasons, to also store a list of teams inside the User model, and that would be a headache, because then you would need to manage two lists of relationships, which is quite bad from a data consistency perspective.
For sure. One of my main reasons for doing it the way I am now is because the User_To_* tables were going to have a another field for misc type of flags. For example my User_To_Event table tracks every user to every invite that they're invited to, but also holds a flag for their RSVP status (ie, Going, Not going, Tentative). I'm not overly familiar with NoSQL structure. Any idea how I would accomplish this without doing it the way I did?
I'm not 100% sure, but in that case I think you would need to stay with your current data model, and add a status column in the User_To_Squad table. Considering how Parse currently handles this kind of data relationship, it would also have an impact on your query count, and thus, on your monthly bill...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.