Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Pulling Fitbit data into a Rails application

I'm working on a small Rails application that I'd like to pull my Fitbit JSON data into.

 

Background

 

The app is running on Ruby 2.2.2 and Rails 4.2.3. Authentication is handled with Devise, and I managed to implement omniauth-fitbit so that I can login to the app using Fitbit.

 

That part seems to be working okay so far. Here is the code from app/models/user.rb where I set some of the data for the user:

 

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.provider = auth.provider
      user.uid = auth.uid
      user.oauth_token = auth.credentials.token
      user.email = auth.info.nickname + "@fitbit-temp-email.com"
      user.password = Devise.friendly_token[0,20]
      user.password_confirmation = user.password
    end
  end

I can access a Rails console and see that the user has been saved with the proper provider, uid, and oauth_token fields.

 

Issue

 

Now that I have that data saved, I'm not sure how to make requests in such a way that Fitbit will allow me to pull the data in!

 

I installed the faraday gem in hopes of using that to make requests and get responses back from Fitbit, but I'm not sure what I'm doing.

 

As an example, I'd like to be able to access my Fitbit profile JSON data here:

 

https://api.fitbit.com/1/user/22YFRH/profile.json

 

But I can't seem to figure out how to format the request correctly. I always get this response:

 

{
  errors: [
    {
      errorType: "invalid_request",
      message: "Authorization header required. Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."
    }
  ],
  success: false
}

 

I have the user's auth_token saved, but how do I use that to generate an access_token. And how do I use that access_token to create a request that returns a successful response?

 

As a side note, forgive me if some of this barely makes sense. I'm clearly new to some of this authentication stuff and it's been tough figuring out how all these things fit together when the documentation seems to make a lot of assumptions about what is already known. And I've found some great tutorials that realy helped in terms of getting started, but many are outdated or only go so far.

 

/cc @JeremiahFitbit

Best Answer
0 Votes
3 REPLIES 3

So the good news is that I ended up getting some of this to work using the excellent fitgem library. And I think I'm going to stick with that for now while I build out more features of my Rails application.

 

The only problem is that gem uses OAuth v1.0, which is being deprecated. I had started to work towards using faraday with OAuth v2.0 as a way to pull in JSON data from my Fitbit profile, but I never quite got it to work. I'll try putting some more work into this at some point in the future, but in the meantime feel free to ping me if anyone else figures this out!

 

 

def fitbit_profile
    conn = Faraday.new(:url => 'https://api.fitbit.com') do |faraday|
      faraday.request  :url_encoded             # form-encode POST params
      faraday.response :logger                  # log requests to STDOUT
      faraday.adapter  Faraday.default_adapter  # make requests with Net::HTTP
    end

# POST Example from Fitbit API Docs # POST https://api.fitbit.com/oauth2/token # Authorization: Basic Y2xpZW50X2lkOmNsaWVudCBzZWNyZXQ= # Content-Type: application/x-www-form-urlencoded # client_id=22942C&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fexample.com%2Fcallback&code=1234567890 access_token = conn.post do |req| req.url '/oauth2/token' req.headers['Authorization'] = "Basic #{user.oauth_token}" req.headers['Content-Type'] = 'application/x-www-form-urlencoded' req.body = "client_id=22942C&grant_type=authorization_code&redirect_uri=http%3A%2F%2Fexample.com%2Fcallback&code=1234567890" end
# GET Example from Fitbit API Docs # GET https://api.fitbit.com/1/user/-/profile.json # Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0MzAzNDM3MzUsInNjb3BlcyI6Indwcm8gd2xvYyB3bnV0IHdzbGUgd3NldCB3aHIgd3dlaSB3YWN0IHdzb2MiLCJzdWIiOiJBQkNERUYiLCJhdWQiOiJJSktMTU4iLCJpc3MiOiJGaXRiaXQiLCJ0eXAiOiJhY2Nlc3NfdG9rZW4iLCJpYXQiOjE0MzAzNDAxMzV9.z0VHrIEzjsBnjiNMBey6wtu26yHTnSWz_qlqoEpUlpc faraday_response = conn.get do |req| req.url '/1/user/-/profile.json' req.headers['Authorization'] = "Bearer #{access_token}" req.headers['Accept'] = 'application/json' end end

 

 

 

 

Best Answer
0 Votes

I was bummed that I couldn't get much help here when I posted this thread, but I figured I'd follow up in case anyone else came across this post.

 

I ended up sticking with the Fitgem implementation since I managed to get that working.

 

But for anyone looking for a good OAuth v2.0 implementation then I'd recommend checking out this project since it looks like it might help get you on the right track:

 

http://www.colinw.info/portfolio/fitbit

https://github.com/ColDog/oauth2-fitbit-rails

Best Answer
0 Votes

In case you are still looking for a gem for OAuth2, here is one that I wrote

 

https://github.com/gupta-ankit/fitgem_oauth2

 

 

Best Answer
0 Votes