aarondcoleman / fitbit.net Goto Github PK
View Code? Open in Web Editor NEWFitbit .NET API Client Library
License: MIT License
Fitbit .NET API Client Library
License: MIT License
This is a great API! Thanks for putting it together!
I added the LogWeight method that I needed it for my project. I am happy to submit a PR with it.
I have a couple of questions before I get started:
Newbie here. Not native to c# and also stumbling on git. But if I can get these going I would love to participate.
Here's the thing - I just signed up to the fitbit apis. I can get the master branch to build and execute.
However my understanding is that I need to get up to speed on oauth2.
When I switch to branch async-portable-oauth2-tokenstore I can't get a clean build.
Can anyone point this newbie in the right direction.
Am I on the right branch for oauth2?
Is it likely an environment issue? Do I just need to slog through the error messages.
Thanks for all your help.
Vic
The constructor for FitBitClient has redundant arguments. The Httpclient
argument is to be used if we have a client whose authentication headers have already been set, hence there is no need to provie an implementation of IAuthorization
(client is already authorized). And vice-versa, if we are providing an implementation of IAuthorization
then we want to take care of creating an authorized HttpClient
through there and there is no need to pass our own client.
Possible solutions:
IAuthorization
and another one were we simply pass HttpClient
HttpClient
as an argumentThoughts?
Current SubscriptionManager
implementation depends on RestSharp. We need to re-implement functionality without dependency on RestSharp.
If we are retiring V1, do we still need FitBit.Common or can that be merged into FitBit.Portable to have a single project?
Hi,
There is any support for obtaining Oauth2 token for the already generated oauth1 tokens?
According to the Fitbit api documentation each response returns additional information about its rate limits. This information might be useful to be parsed out.
I'm not sure where it should go or if it would be useful or what the use case would be but thought I would add this issue to allow for discussion.
Further info - https://dev.fitbit.com/docs/basics/#response-headers
The following line is in the Global.Asax.cs
file in the portable sample project which is required for any of the remote calls to work:
OAuthUtility.ComputeHash = (key, buffer) => { using (var hmac = new HMACSHA1(key)) { return hmac.ComputeHash(buffer); } };
This should be documented or automated (if ComputeHash isn't set)
I'm using the async-portable branch
I just put into the Azure WebApi2 project, and call:
FitbitClient client = new FitbitClient("824d4b38500e4b90bd02655c29338e93",
"82...........",
currentUser.fitbit_oauthtoken,
currentUser.fitbit_oauthsecret);
Activity dayActivity = client.GetDayActivity(new DateTime(2015, 2, 1));
then i got "Http Error:Unauthorized" on the getDayActivity call.
Any idea why?
I didn't fully appreciate this until the other day but there are two types of authentication into the Fitbit API:
Guess we need 2 "authorization" interceptors?
Here's the deal -- this is an HTTP plumbing library and .NET introduced the "async" modifier since to allow for clever thread repurposing while things like HTTP and / IO are waiting for responses. Microsoft and the .NET OSS community have also made great progress in Portable Class Libraries (PCL) which are common denominator projects that can span all the subset .NET frameworks (Windows Phone 8, Xamarin, Silverlight, etc). Not everyone is down with async yet either in the .NET community, there's a slight learning curve.
If I were to start this library over again from scratch I'd
Not use restsharp as it isn't PCL compatible (but a small stalled branch is) and doesn't use the async modifier (though it has an older style async callback structure).
Not consume the XML endpoints from Fitbit as the JSON ones seem to get a little more love from their API team and on several occasions malformed XML with debug data has caused issues. Plus, everyone loves JSON.net and serialization/deserialization speed.
We have some ideas on how to start to move to this, but it likely means breaking changes or a non PCL. I for one would like to start using async versions of parts of the client library right away in parts of my project that are most frequently called (GetUserProfile, TimeSeries, and DailyActivity) but cannot in one swoop replace all the methods.
So, I'm open to ideas. We might continue a long branch offshoot so we can make progress in both, we might merge the projects with a common project where sync and async/pcl live, and we might just say screw it and start an entirely new project.
Myself and @WestDiscGolf have already started exploring technically how to do this. See:
Chime in with feedback.
--Aaron
... and replaced with something more appropriate.
The below is too much and clutters up FitbitClient.cs
public FitbitClient(IAuthorization authorization, HttpClient httpClient = null)
{
if (authorization == null)
throw new ArgumentNullException(nameof(authorization), "Authorization can not be null; please provide an Authorization instance.");
Authorization = authorization;
if (httpClient == null)
this.HttpClient = new HttpClient();
else
this.HttpClient = httpClient;
this.HttpClient = authorization.CreateAuthorizedHttpClient(); //use whatever authorization method to provide the HttpClient
}
/// <summary>
/// Use this constructor if an authorized httpclient has already been setup and accessing the resources is what is required.
/// </summary>
/// <param name="httpClient"></param>
[Obsolete]
public FitbitClient(HttpClient httpClient) : this(string.Empty, string.Empty, string.Empty, string.Empty, httpClient)
{
}
/// <summary>
/// Use this constructor if the access tokens and keys are known. A httpclient with the correct authorizaton information will be setup to use in the calls.
/// </summary>
/// <param name="consumerKey"></param>
/// <param name="consumerSecret"></param>
/// <param name="accessToken"></param>
/// <param name="accessSecret"></param>
[Obsolete]
public FitbitClient(string consumerKey, string consumerSecret, string accessToken, string accessSecret) : this(consumerKey, consumerSecret, accessToken, accessSecret, httpClient: null)
{
// note: do not remove the httpclient optional parameter above, even if resharper says you should, as otherwise it will make a cyclic constructor call .... which is bad!
}
/// <summary>
/// Private base constructor which takes it all and constructs or throws exceptions as appropriately
/// </summary>
/// <param name="consumerKey"></param>
/// <param name="consumerSecret"></param>
/// <param name="accessToken"></param>
/// <param name="accessSecret"></param>
/// <param name="httpClient"></param>
[Obsolete]
private FitbitClient(string consumerKey, string consumerSecret, string accessToken, string accessSecret, HttpClient httpClient = null)
{
HttpClient = httpClient;
if (HttpClient == null)
{
#region Parameter checking
if (string.IsNullOrWhiteSpace(consumerKey))
{
throw new ArgumentNullException(nameof(consumerKey), "ConsumerKey must not be empty or null");
}
if (string.IsNullOrWhiteSpace(consumerSecret))
{
throw new ArgumentNullException(nameof(consumerSecret), "ConsumerSecret must not be empty or null");
}
if (string.IsNullOrWhiteSpace(accessToken))
{
throw new ArgumentNullException(nameof(accessToken), "AccessToken must not be empty or null");
}
if (string.IsNullOrWhiteSpace(accessSecret))
{
throw new ArgumentNullException(nameof(accessSecret), "AccessSecret must not be empty or null");
}
#endregion
HttpClient = AsyncOAuth.OAuthUtility.CreateOAuthClient(consumerKey, consumerSecret, new AsyncOAuth.AccessToken(accessToken, accessSecret));
}
}
A bit of house cleaning-- starting in V2.7 nuget released a new/more robust package restore approach.
Details here: http://docs.nuget.org/consume/package-restore/migrating-to-automatic-package-restore
As part of the initial re-work almost a year ago I added in a FitbitResponse
- https://github.com/aarondcoleman/Fitbit.NET/blob/async-portable-oauth2implement/Fitbit.Portable/FitbitResponse.cs - as a wrapper around the response to handle the data returned from the api end points to determine the status of the response etc.
What are peoples thoughts on this? Should it be kept? Should the client return the raw model and handle errors differently? How are people handling rate limits and accessing the Retry-After
http header (https://github.com/aarondcoleman/Fitbit.NET/blob/async-portable-oauth2implement/Fitbit.Portable%2FFitbitResponseExtensions.cs)?
It would be really good to get some feedback from people starting to use the beta PCL v2 library to see where we can improve the usability against the library api surface.
First of all thanks for the great project! I am using the desktop version successfully for several months. I also wanted to start using the web version but I am having dificulties running the SampleWebMVC project.
Parser Error Message: Could not load file or assembly 'System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
Line 31:
I have tried to resolve this by changing assembly versions but never got it working.
Is there anything I am missing? I am using Visual Studio 2013.
Hello,
I have been using this client library for a while and it has been working great. However, today I started seeing errors when trying to get approval for my FitBit App. The problem occurs in the Authenticator.ProcessApprovedAuthCallback() method with a response of:
{"errors":[{"errorType":"oauth","fieldName":"oauth_access_token","message":"Invalid signature or token 'xxxxxxxxxxxxxxxxx' or token 'xxxxxxxxxx'"}],"success":false}
I see that there was a security update to the FitBit API yesterday and I downloaded the new Fitbit.NET library that was put up a few hours ago (it added "private readonly IRestClient client" as a datamember of Authenticator among other changes). Unfortunately, I am still getting the error.
I tried switching the app over to be a "Desktop App" and using GetAuthCredentialFromPin() and it worked great, but not using ProcessApprovedAuthCallback().
Does this sound like it may be related to the API security fix and any idea what might cause this error?
Appears to fail on LastWeekActiveScore() and is missing Session["FitbitAuthToken"].ToString() and Session["FitbitAuthTokenSecret"].ToString())
Thoughts on what I'm doing wrong? I've registered an application and modified the Web.Config with a proper FitbitConsumerKey and FitbitConsumerSecret.
Thank you!
Hi,
I was reading the Fitbit API docs and it says their new devices, Charge, Charge HR, and Surge, will only be supported though OAuth 2.0 endpoints. Also it says they're planing to transition to OAuth 2.0 in the coming months.
My question is, do you have plans to support OAuth 2.0 in this project?
Thanks for all the work you've already done on this very useful project.
Regards,
Daniel
Hi,
I downloaded the project and I tried to open it but it wouldn't load .It gives me an "The project type is not supported by this installation" error.I would really appreciate your suggestions on this issue.
-Sandeep
After geting the project to build. I can't seem to get the amount of steps. I am using the async-portable branch for the o auth 2 app. Authorization goes just fine. But loading the LastWeekSteps returns an null void exception. Specifically the response.data. I am quite sure my fitbit has logged steps every week.
Hi,
I am using your great client library in an existing project, that I will need to upgrade soon, in order to be able to keep accessing the Fitbit API, as they are deprecating v1 of the API.
What is the status of this client library? :)
It seems that a lot of the endpoints are already implemented (on branch async-portable-auth2implement), and that a design for implementing a token store has been proposed on branch async-portable-auth2-tokenstore - is that correct? I am not completely sure on what branch to go from?
I have a service running in the background on my server, that is handling the synchronisation of data from Fitbit to my system. I already save tokens, but it seems like the token store solution would be the way to go - especially now that I have to update my own implementation to handle refresh tokens.
How would I go about extending and implementing the proposal you already have - any things I should keep in mind, or have you already implemented this elsewhere?
I am sorry if I'm asking about things that is documented elsewhere, but the structure of this project is not totally clear to me. I look forward to hear from you with some guidance.
Carrying this over from @WestDiscGolf previous comment here: #46 (comment)
I've been thinking about the library as a whole with everything we've discussed over the past 6-12 months and looking/using other libraries recently it's allowed me to see how others have approached a similar issue and addressed it. I also had an issue with how big the "FitbitClient" class was getting as it was getting too unweilding. So taking all this into account I've had a bit of a play and finally got around to publishing the results. It's a bit raw and the tests project doesn't build but the methods I've implemented (GetDevices, Get friends) work - https://github.com/WestDiscGolf/Fitbit.NET/tree/async-portable-update
It's only a potential idea, so wanted to put it out there before going too far. Let me know what you think.
Cheers
I took a look and it seems like you're proposing we create, sort of a mini-client per category of the API client class? Like, DevicesClient and FriendsClient? Hmm, I'm not sure that's any more clearer. What about keeping the FitbitClient class intact and using partial classes such that we can group resource collection calls together? Like:
There are a number of links to old api documentation in the source and these should be updated to the new links.
When a friend hasn't set their date of birth the json response which comes back has the value as ""
which doesn't parse as a valid date time when you request the users friends.
Hello Aaron,
I trying many time, why fall pairing with Fitbit. According to my researching you may
transmit by session more things.
Because when you generating in Callback something this
RequestToken token = new RequestToken();
token.Token = Request.Params["oauth_token"];
token.Secret = Session["FitbitRequestTokenSecret"].ToString();
token.Verifier = Request.Params["oauth_verifier"];
and after this action are values
token.Token = null
token.Secret = "some code from working at Authorize"
token.Verifier = null
In my code before your solution I transmit Secret and also Token from Authorize to CallBack.
I think that Secret and Token are necessary for method GetAuthCredentialFromPin, too.
Milan
Hello,
I am coder in asp.net MVC4. My boss was given me a task add Fitbit oAuth to my website project. And when I found your solution, I said in my mind "Supr I have done it". BUT I read yours project and in my oppinion is a nonstandard solution opposite to examples on http://www.asp.net/mvc/tutorials/security/using-oauth-providers-with-mvc
Have It a some reason or is It yours laziness do something kosher (right,correctly).
Thanks for
replies
This is a big one, but I'm interested in help and suggestions on how to move this library to support C# 5 async and Task based returns. Ideally every existing Method XxxxXxx() would have an accompanying XxxxXxxxAsync() (with the "Async" postfix) version.
HOWEVER, the state of RestSharp's support for async isn't determined. There is a branch now called "portable" that has most of RestSharp ported to use HttpClient and supports ExecuteAsync:
Discussion:
restsharp/RestSharp#468
Branch:
https://github.com/restsharp/RestSharp/tree/portable/RestSharp
It lacks OAuth support that the thread poses the question whether they even should support it (yes, I'd say) since there exist so many libraries already.
Another similarly named but independently developed fork:
https://bitbucket.org/fubar-coder/restsharp.portable/overview
An independent OAuth library which claims to do OAuth authentication in async/await form:
https://github.com/neuecc/AsyncOAuth
Thoughts / suggestions? You can help by testing some of these libraries, contributing to them or Fitbit.NET, and / or suggesting some alternative ways.
I've running through the steps to get integration test running, but "Step 2" keeps failing. Stepped through and found that the URL https://api.fitbit.com/oauth/access_token is returning 404. Not sure where to go from here.
Hi, forgive me if I've got this wrong, but does the Fitbit.IntegrationTests.AuthenticationTests contain incorrectly hardcoded url's?
Shouldn't this....
public AuthenticationTests()
{
authenticator = new Fitbit.Api.Authenticator(Configuration.ConsumerKey,
Configuration.ConsumerSecret,
"http://api.fitbit.com/oauth/request_token",
"http://api.fitbit.com/oauth/access_token",
"http://api.fitbit.com/oauth/authorize");
}
read like this....
public AuthenticationTests()
{
authenticator = new Fitbit.Api.Authenticator(Configuration.ConsumerKey,
Configuration.ConsumerSecret,
Configuration.RequestTokenUrl,
Configuration.AccessTokenUrl,
Configuration.AuthorizeUrl);
}
The time value of the intra day data parsing gets the value from the Time property in the json however as the parent node isn't referenced and the actual day you are parsing isn't passed in the value defined is actually the current date - this fails the unit test. I believe this to be a valid failure as I would expect the time of the intra day value to be linked to the request day date
Including the dependency on AsyncOAuth as no longer required for oauth 1 support
Hi,
How can we refresh the token for Oauth2?
I am trying to add this package to a Xamarin studio solution using Nuget.
Unfortunately it fails with the following error:
Could not install package 'Fitbit.NET 1.0.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
Have you ever seen it?
OK everyone -- let's plan for something we don't actually have our hands on yet but is imminent: The migration to OAuth 2.0.
From what I understand from Fitbit's plans:
In order to assist people who are going to slowly migrate their application over I'd like to keep the following guiding principles in mind for this wrapper library:
I think Adam and I have hit a lot of these already so far in this branch.
In terms of OAuth 2.0 we have 2 options (or more, seeking input):
For 1. I'm thinking something like:
public class OAuth2Authorization : IAuthorization
{
public override HttpClient AddAuthorizationHeader(HttpClient existingHttpClient, ....)
{
//adds in the auth header
}
}
OR for 2.
public FitbitClient(string consumerKey, string consumerSecret, string accessToken, string accessSecret) : this(consumerKey, consumerSecret, accessToken, accessSecret, httpClient: null)
{
// this one calls the private constructor with the params needed for OAuth 1.0A
}
public FitbitClient(string consumerKey, string consumerSecret, string bearerToken) : this(consumerKey, consumerSecret, bearerToken, httpClient: null)
{
// this one calls the private constructor with the params needed for OAuth 2.0 (one less param)
}
Also, this is how simple it should be to add the Authorization component to an HttpClient for OAuth 2.0, but again, I haven't seen the Fitbit implementation yet:
//added helper code for OAuth 2.0 header setting
private void SetHttpClientAuthorizationBearerToken(string token)
{
AuthenticationHeaderValue authenticationHeaderValue = new AuthenticationHeaderValue("Bearer", token);
this.HttpClient.DefaultRequestHeaders.Authorization = authenticationHeaderValue;
}
Seeking input in comments below. Examples of how this was handled elsewhere?
--Aaron
@aarondcoleman @mxa0079 and I discussed exception handling and throwing exceptions at the weekend and it was deemed that we should have a couple of exceptions which derived from a base FitbitException
as per version 1. However they would be slightly more focused to allow consumer code to handle different issues without having to inspect the type of status code the exception had first. This would also allow for future scenarios to be handled on a case to case basis and additional exceptions to be included over time if required.
This issue is here as place where discussion can be made on the initial implementation see #75
Hello Everyone,
Fitbit updated their API to bring it more in compliance with the OAuth 1.0a spec. This library wasn't fully in compliance, and to do so I determined that it was better to refactor a more correct implementation of the flow than to hack on. As such, your code compile will fail in the right places once you reference these new pushes and require you to store (in Session, database, or in memory the RequestToken.Secret) during the OAuth dance.
See this Wiki Entry for more explanation:
Logging this issue so we can keep track of the items we need as a minimum for documentation to get done once the API surface has been finalised (think we're only waiting on the constructor now?).
I'm sort of tattling on myself here, but in the FitbitClient.GetSleep method, the Summary returns correctly, but the list of sleep logs comes back null.
I merged in a pull request that had this issue, a fix will be coming soon. Essentially the fix is to change this class as follows;
public class SleepData
{
public List Sleep { get; set; }
public SleepSummary Summary { get; set; }
}
This allows RestSharp to correctly parse the response. I'll also be committing tests for this.
I'm proposing adding in an optional constructor parameter and an interface that would allow a FitbitClient users to log raw HTTP calls / responses. This accomplishes a couple things:
Thoughts?
I'm successfully using this as part of a project but it would be much better if I could install a NuGet package for it.
Thanks for your great work.
Hi,
There is any posibbility to access RemoveSubscription using the new library?
Hello Aaron,
I have a project based on yours and it is giving me and error. I get the same error when I try running your riginal code. The application always crashes with : „Conflicting versions of ASP.NET Web Pages“.
This issue did not come up with an older version of the project, I still have downloaded.
I tried to figure out the differences between the two versions and found out that some libraries have been updated or added.
However according to References you only added Microsoft.AspNet.WebPages.3.0.0, bud did nothing with the "web.config" files.
I created a new project and I think there is something missing in the web.config of your project.
The following part was in the newly created web.config but not in Sample MVC:
<runtime>
<assemblyBinding.....
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="..........." /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
Also :
<compilation debug="true" targetFramework="4.5">
<assemblies> .....
<add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
I am not a programming guru, but could this be what causes the crashes? I think, there are two possible solutions.
I think the first solution might be easier.
There is an issue in getting the time stamp for making calls.
As per the time zone of Aus, having daylight-saving time, calculated time stamp is wrong for making call to method GetRequestToken().
I used Network Time Protocol request for time stamp calculations, hurray, I got Success.
Still I am not sure weather this is the right way to go on.
Thanks,
Jigar Shah
It would be really good if a nuget package version of this could be setup to aid with adding to existing projects.
We're currently running on version 6.0.3 of Json.Net which came out in March 2014 and the current version is 8.0.2 (https://www.nuget.org/packages/Newtonsoft.Json/), which is 2 major versions behind. Thoughts?
A set of tests have been tagged with: [Ignore("Re-enable when exceptions have been introduced")]
Well... the exceptions have been re-introduced so it is time t bring them back on board. This should be done before RC to ensure no major functionality has been broken as part of new functionality.
I think this project is outdated as this no longer returning anything from fitbit. Also fitbit no longer support xml which this library uses. Fitbit only returns data in json format. Any way to make this library work by editing it?
If a user revokes access it crashes:
Under HandleResponse it throws an exception:
Additional information: Http Error:Unauthorized
When I call GetWeight with just a start date I get the following exception: "Input string was not in a correct format." If I call it with a start and end date I get the following error: "Http Error:BadRequest" I have no problems at all calling GetDayActivitySummary and GetSleep. Here is an exerpt of my code:
DateTime start = DateTime.Parse("3/1/2013");
DateTime end = DateTime.Now.Date;
var fitbit = new FitbitClient(consumerKey, consumerSecret, userToken, userSecret);
var weightlog = fitbit.GetWeight(start, end); //this is the line it fails on
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.