Wednesday, September 25, 2013

A parse.com tutorial - implementing a friends list

I've been playing with Parse in my spare time recently, and a couple of topics seem to come up quite often: relationships and some kind of "friends list" functionality.

A "friends list" is a great example of a many-to-many relationship. Seems to me that a tutorial of how to add a "friends list" would solve both these questions, so that's what I'm doing.

Requirements

First lets think of what a "friends list" should entail:
  • Find a person
  • Add them to my friends list
That's it! We're done, right? Well often you want to allow people to approve/reject being friended. You'll want to have the friendship be both ways (if I add you to my list, then you get to add me to yours). There's all sorts of extra things to consider.

Revised Requirements

Here's an expanded list, lists first:
  • Find a person
    • Highlight if I already have them in my friends list, or have asked
  • List requests from others waiting for my approve/reject action
  • List my friends
  • List my requests that are pending
  • List my rejections
  • List requests I have rejected
Now for actions we want to be able to perform:
  • Request to add someone as a friend
  • Approve a request
  • Reject a request
  • Un-friend
  • Things we could add later:
    • Un-reject (change to approved, in case someone makes a mistake)
    • Re-request (possibly with a time-window to prevent abuse)
We will leave off things like showing how many friends you have in common etc.

Given these requirements, a Parse class like the following should give us what we want:

Class: FriendRequest
RequestFrom (reference: User)
RequestTo (reference: User)
Status (string: requested/approved/rejected/etc)

So, lets see how we can handle the above lists and actions:

Find a person (highlight existing status)

Once your existing "find a person" query is run, you would need an array of User objects. Using this list we could ask for all FriendRequest objects where RequestFrom is in the list or RequestTo is in the list.

List requests from others waiting for my approver/reject action

Query FriendRequest where the current user is the RequestTo and the status is "requested".

List my friends

Query FriendRequest where the current user is RequestFrom or RequestTo and the status is "approved".

List my requests that are pending

Query FriendRequest where the current user is RequestFrom and the status is "requested".

List my rejections

Query FriendRequest where the current user is RequestFrom and the status is "rejected".

List requests I have rejected

Query FriendRequest where the current user is RequestTo and the status is "rejected".

Well, looks like we can handle all the requests, what about the actions?

Request to add someone as a friend

First make sure there's no existing record with the current User and the target User as RequestFrom/RequestTo or the other way around.

If that requirement is met then you just need to create a new FriendRequest object with the following properties:
RequestFrom: current User
RequestTo: target User
Status: requested

Approve a request

Change the Status from "requested" to "approved".

Reject a request

Change the Status from "requested" to "rejected".

Un-friend

Change the Status from "approved" to "rejected".

Summary

In theory it looks like everything is covered, though I welcome comments and feedback if you think I'm missed anything or made a mistake.

I'll post some sample code (JavaScript and maybe some Objective-C too) once I get my code formatting working again.

Things I'm playing with now

Wow, it's been a while since I've updated this blog. Looks like my code-formatting broke too.

Anyway, lots of things have changed, but here's what I am looking at recently:
  • Parse.com, a data backend with SDKs for all major platforms: JavaScript, iOS, Andriod, .NET as well as REST
  • LINQ, specifically PredicateBuilder that lets you build OR logic, as well as building expressions and having them translated into SQL calls
I'll see if I can post some tutorials on using Parse some time soon.