doubleclickdetroit / rounds

mobile game
2 stars 0 forks source link

return relevant user data on session#create #67

Open bchase opened 12 years ago

bchase commented 12 years ago

including:

unread invitations count
watchings count
gamification
  points/currency
  rank
user abilities
system messages

basically the idea here is that as soon as the user logs in we're going to want to show them an unread invitations badge and subscribe them to round locks they were watching (perhaps a bit of an edge case) and so on.

by just showing the counts, we dont push the db too hard to get this data, it gets encapsulated in a single http request, and subsequent requests need not be made unless the return shows a >0 count for a resource. :sparkles:

bchase commented 12 years ago

@benbabics i got started on this and then realized that im doing a redirect_to with :notice at the moment. do you think sessions#create should return json and then we can redirect via backbone?

benbabics commented 12 years ago

Let me see if I understand what you're asking. :)

Currently you have rails handle the login process which, upon success, sets the cookie, sets the :notice and does a redirect. As you mention in your first post, on app-start there is data that needs the client-side needs and what is the best way to do that? Is that correct?

I like session being handled by Rails. As we discussed early on, Backbone can simply facilitate the game and remain agnostic of the state of session. It's cleaner that way. Please do let me know if you see a flaw with this... I'm open to your opinion. :sparkles:

With that said, if we are allowing Rails to handle the redirect after the session#create then we'd have to fetch data via ajax, as we can't just have Rails return JSON as there wouldn't be a receiver for this data in JavaScript. It would need to be fetched.

As for the data you mention in your first post, it seems to me that the 2/3 of the data

unread invitations count
watchings count
gamification
  points/currency
  rank

appears to be served under /api/users/me

GET /api/me
      GET /api/users/me/invitations/
      GET /api/users/me/slides/
      GET /api/users/me/comments/
      GET /api/users/me/ballots/
      GET /api/users/me/watchings/
      GET /api/users/me/dibs/

and it seems to me that this data- with the exception of the invitations count- only needs to be requested when the user hits the me tab anyways... not necessarily on app-start. Though maybe I've overlooked something?

So, going back to what I said above- if we stick with Rails handling the redirect then I'd guess on app-start we'd need to make a request for pertinent data which, to me, seems like the following:

unread invitations count
user abilities
system messages

Moreover, unread invitations count IMO should be Pub/Sub for the Facebook game as it's Push, I think, for Mobile. Now that is my assumption, and I may be wrong, so I filed an issue for that. I guess my question for you would be, if we make this Pub/Sub, upon our subscription will it publish to the client if there is already data queued there? If not, it may be worth extending to do that to avoid the request. Otherwise, we'd need to request it with the list I shortened above and still do the subscription. Does that make sense?

So, if we can do Pub/Sub for unread invitations count then our list would be even shorter:

user abilities
system messages

Doesn't that seem much more manageable and less redundant? That's what I figure anyways. If that's what our list would look like then it seems we could do a request that serves data related to session settings or game configuration. e.g. /api/users/me/config.

Or maybe I'm COMPLETELY wrong and wasted 15 minutes of my life. LOL! Completely plausible. Please let me know what you're thinking. :)

benbabics commented 12 years ago

So I have something stubbed out to handle the login client-side with Facebook. What URI should I hit, which data should I send, and what should I expect back? IMO, the Canvas app should somewhat mirror the login as closely to the iOS app as possible to maintain similar implementation where it's hitting the same URI and passing/receiving the same data.

This is what I'm receiving:

accessToken: AAADaG1FKJ5QBAG6lRbWYs8j6jh4DHzOuFPOM5ksDAbDw4wEVOJTIMOcbyXM949q8UZBt7G9Q8K9v5IheFnztjRWztoXSDhuge45DFcwZDZD
expiresIn: 6198
signedRequest: C5DgB3Rn14Z2lnmBC5THJsBAEGLUCnDRhjnwThyLGrw.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiIyLkFRRFdoQlJuUE1lWkpOTEcuMzYwMC4xMzQwNTg5NjAwLjEtNTAwMDMyMjc3fERsMERPVlZzN1VCRE5XMldWTDZyVTdxT2lrVSIsImlzc3VlZF9hdCI6MTM0MDU4MzQwMiwidXNlcl9pZCI6IjUwMDAzMjI3NyJ9
userID: 500032277
bchase commented 12 years ago

looks like i have this working:

Setting friend ids

POST /api/users/me/friends {provider:'facebook', uids:[1,2,3]}

the response will be the user ids of friends that were found in the system.

im not sure the exact format since im just doing a render json: @user_ids but it will have an array of user ids in it somewhere.

bchase commented 12 years ago

as for mirroring the iOS process, i feel like im forgetting a point you made about not having a specific kind of data on the page after or before a login... or something.

also, to be clear, the posting of friend provider/uids is explicit (hitting the path above) and should be the same for both clients.

(please note the alternating domain names below) here is the login process for the backbone app as i understand i have it implemented now:

user not registered

  1. the user hits a page in the application without a session
  2. some action, currently a simple <a>, takes the user to http://ourservice.com/auth/facebook
  3. omniauth (or some form of magic) redirects this to http://facebook.com/auth # or something like this where the user has to accept the app permissions. after this completes and the user is authenticated with facebook...
  4. facebook redirects the user to http://ourservice.com/auth/facebook/callback which is routed to our sessions#create. this action is looking for an auth hash that has been passed along which contains the provider, uid, and token.
  5. using the data listed above (and name and profile picture), an Authentication is created for the provider/uid and is linked to a new User record.
  6. session[:user_id] is set to @new_user.id and the user is now officially registered and signed in

what i was saying to ammar on our call the other day is that if he has the data for that auth hash in hand, he can just hit the route for the facebook auth callback directly, thus passing that into sessions#create which doesnt really care where it comes from, just that its valid (with facebook).

so if you want to do that with the backbone app too, by all means, go for it :grin:

bchase commented 12 years ago

@benbabics let me know if i missed something or if i didnt answer your question, but this is all i can think of on the topic.

also, what was it that we said we were going to need to have in the page? i feel like it had to do with a Collection.reset() on something?

benbabics commented 12 years ago

@bchase Nope, I'm ok with leaving it as is. So, rails is handling the managing the session with the standard HTTP requests; if they're not logged-in, they are once the click the link and the page is reloaded and vice versa when they are logged-in and want to log out. Is that correct? If it is, then the only thing I'm looking for is for you to bootstrap "config" data? Some or all of the data below?

unread invitations count
watchings count
gamification
  points/currency
  rank
user abilities
system messages

I'll just need to investigate with RequireJS how to define a module on the page to bootstrap with. It's different than normally loading a module because

define ['foo','bar'] (Foo, Bar) ->

means that they came from

foo.js, bar.js

instead of being embeded on the page between <script></script> tags.

bchase commented 12 years ago

@benbabics perfect. correct about the login/logout functionality.

and that was exactly what i was forgetting. i havent worked on it yet, but once i do, ill make sure i dump that json in a <script> and then you can do with it what you like :sparkles:

bchase commented 12 years ago

after i attach anything i can get my hands on to the global scope #nobutcanyouimagine

benbabics commented 12 years ago

LIKE

benbabics commented 12 years ago

So, being mindful of the request that client-side we need to access the FB API and fetch the friends list, we need to ensure that the session is maintained between our app and Facebook. Below I will state my case in the browser, which I realize may be entirely different than iOS, but it may be the same.

  1. Inactive Session on What The?
  2. Inactive Session on Facebook.com
  3. What The? renders link to login
  4. Click link to log onto What The?
  5. HTTP request to Facebook servers are made
  6. Facebook sign-in form is rendered
  7. Enter credentials and submit
  8. HTTP request to What The? servers are made
  9. What The? landing page renders
  10. Client-side async loading of Facebook API
  11. JavaScript FB.init appId:123, status:true invoked to
  12. JavaScript FB.Event.subscribe 'auth.statusChange', (response) ->
  13. auth.statusChange event is triggered and callback is passed the response object because Facebook session is active.
  14. Open new tab to test session is active on Facebook.com... session is indeed active
  15. Using Facebook.com in the new tab, logout of current session
  16. Return to What The? tab and reload
  17. What The? still maintains an active session
  18. Repeating steps 10, 11, 12- auth.statusChange event is not triggered because, per Facebook API, we do not hold an active session.

This may seem like a minor issue, however, it seems to me that because we need to be in communication with Facebook API client-side, we need this to be in-sync ( or :sparkles: N'Sync :sparkles: ) so we're not requesting the user provide authentication twice; once to log into What The? servers and again (if logged out of Facebook.com) when the need arises to communicate with the Facebook API client-side.

Please let me know if I need to clarify, or if I'm perhaps overlooking something?

bchase commented 12 years ago

:+1: N'Sync reference

im going to read this more thoroughly and get back to you on whether or not i understand it :smile:

we have a call tomorrow?

benbabics commented 12 years ago

Yes. I'm available at any point today, as well as the 5pm call. :smile:

Sent from my iPhone. Please excuse misspellings or shortness of my reply.

On Jun 25, 2012, at 12:03 AM, Brad Chasereply@reply.github.com wrote:

:+1: N'Sync reference

im going to read this more thoroughly and get back to you on whether or not i understand it :smile:

we have a call tomorrow?


Reply to this email directly or view it on GitHub: https://github.com/doubleclickdetroit/rounds/issues/67#issuecomment-6539342

bchase commented 12 years ago

@benbabics

so, i made a first pass at this and think i found a clean way to do this without even using requirejs.

im attaching the json to a span as a data attribute, which jquery lets you easily grab as an object at your convenience in the bootstrapping process with .data()

my attempt can be found here and, as you can see, im intentionally and explicitly polluting the global scope, just because i can :grin:

feel free to change tag types, ids, attribute names, and so on (i honestly dont even like what i chose, i just wanted to get it working)

let me know what you think!

bchase commented 12 years ago

@benbabics close this one out too if you think we're good for now