08-27-2020 22:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-27-2020 22:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hey everbody out there 👋
We have developed native apps for Android and iOS that implement the Fitbit SDK to read the users activity/training and body weight data. This was 2 years ago and so far everything was working perfectly.
Since a few weeks we are having trouble in our Android app with the OAuth flow. Here is an example flow:
- Inside the app the user clicks on a "Connect Fitbit" button
- A WebView opens up for the OAuth and permission flow (https://www.fitbit.com/oauth2/authorize)
- The user sets the required permission and accepts
- The user is redirected to the app where the OAuth flow begins
- Access is granted. Fitbit data is imported into our app and shown there
This is the normal and expected case. So far we were able to repeat this as often as we wanted (or the user wanted). When connected to Fitbit our app shows a "Disconnect Fitbit" button the undo the binding and remove all Fitbit related data from our app. When disconnecting and repeating the connection flow like described above we get an error from the Fitbit API with the following reason:
{
"errors":[
{
"errorType":"invalid_grant",
"message":"Authorization code invalid: dedcacdd0db45cbfab8a00d124059de84d4ed2eb Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."
}
],
"success":false
}
Okay! So we've got a problem here. The docs are - unfortunately - not very helpful ad led to no solution. So we played around and tried different ways and to kind-of-debug the problem. And after some (not very scientific) research we've found a solution to the problem:
- Do step 1 & 2 like described above. We will be automatically logged into our account as we have already visited the website before
- Logout and login again
- Go on from step 3 like described above
Now we are having success *yay*!!! So this seems to be a workaround for our users. And it also seems like we are not doing anything wrong there. We have not changed this flow during the last 12 month and it just stopped working a few month ago.
Let's have a look into the blackbox and behind the scenes:
- When connecting with Fitbit we will firstly generate a randomVerifier and a derivedVerifier. For example:
randomVerifier: xbdWGHY_sUUka111yAvVu3ObIMrZ8pXOOb5hNoTL1o2Ec4r1LHRqC0RAiS_0GhNh2p9XfvAtryyD-Z-pLG0nog
derivedVerifier: 6Z-sktf2D01IWu_2VTIvSe1RQCVV2CV_Wtu7qGzB4SM
- Now we will open up a WebView (Chrome Custom tabs) with the following URL:
https://www.fitbit.com/oauth2/authorize?
client_id=<secret_id>&
response_type=code&
scope=weight activity&
prompt=consent&
code_challenge=6Z-sktf2D01IWu_2VTIvSe1RQCVV2CV_Wtu7qGzB4SM&
code_challenge_method=S256&
redirect_uri=<host>://oauth/fitbit
- Now the flow described above is done by the user. After that the website will redirect to the given uri directly into our app. For example:
<host>://oauth/fitbit?code=dedcacdd0db45cbfab8a00d124059de84d4ed2eb#_=_
- Now we will parse out the code to request an access token from the Fitbit API. Therefore we are building the following url:
https://api.fitbit.com/oauth2/token?
client_id=<secret_id>&
grant_type=authorization_code&
code=dedcacdd0db45cbfab8a00d124059de84d4ed2eb&
redirect_uri=<host>://oauth/fitbit
- Now we will get a response with a http code 400 and the error message mentioned at the beginning of this post. It says we are using an
invalid_grant
We are not having any idea what might be wrong here. It works on the first connect and always after logging out and in again. It also works again after waiting an undefined amount of time. Sometimes it just works again after 24 hours and sometimes it takes up to 3 days. Also this error is only facing the Android platform. iOS is still working like always before...
Is anyone out there facing the same issue? Does anyone knows a solution or has a hint on what we have to do?
Answered! Go to the Best Answer.
Accepted Solutions
09-08-2020 14:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



09-08-2020 14:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @FDDB
Thank you for providing me with your client ID. Looking in our logs for your /oauth2/token requests which are failing with a 400 Invalid Grant error, I see a syntax problem when grant_type=authorization_code.
The parameters and values you're using are
client_id=<client_secret>
grant_type=authorization_code
code=<code_verifier or authorization_code>
redirect_uri=<redirect_uri>
The correct syntax is
code=<authorization_code provided after a user consents>
grant_type=authorization_code
client_id=<6 character client ID that you provided me>
redirect_uri=<redirect_uri>
code_verifier=<code_verifier>
You should never post your client secret in the HTTP request unless you've properly built the Basic token.
Please check your syntax and see if you can make these changes.
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

08-28-2020 16:19
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



08-28-2020 16:19
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @FDDB
Thank you for all the detail. I'm glad you found a workaround. However, it shouldn't be necessary. I would expect you to receive a brand new authorization code when the user tries to consent the second time. Would you confirm that you are receiving a new authorization code?
If the problem is only happening on Android, then I would suspect the behavior is related to Chrome. Can you confirm roughly when this started to occur? Also, it looks like you are using authorization grant flow with PKCE, correct?
Gordon
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

08-30-2020 12:36 - edited 08-30-2020 12:49
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

08-30-2020 12:36 - edited 08-30-2020 12:49
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi Gordon, thank you very much for your reply!
YES, we are receiving a new authorization code (but then getting a new access token with it fails).
YES, we are using authorization grant flow with PKCE.
We also thought about having a chrome problem here so we tried different versions of androidx.browser:
- 1.0.0 (the version we were using from 2018 until July 2020)
- 1.2.0 (we upgraded to in July this year)
- 1.3.0-alpha05 (a few weeks ago for testing)
Unfortunately the problem occurs in all of these versions. We roughly estimate the first occurrance was 4-5 weeks ago.

09-03-2020 08:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-03-2020 08:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hey Gordon,
do you have any ideas on what me might be doing wrong?

09-03-2020 15:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



09-03-2020 15:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @FDDB
Would you please private message me your client ID? I'll like to see what your application is doing.
Thanks!
Gordon
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

09-08-2020 14:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



09-08-2020 14:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @FDDB
Thank you for providing me with your client ID. Looking in our logs for your /oauth2/token requests which are failing with a 400 Invalid Grant error, I see a syntax problem when grant_type=authorization_code.
The parameters and values you're using are
client_id=<client_secret>
grant_type=authorization_code
code=<code_verifier or authorization_code>
redirect_uri=<redirect_uri>
The correct syntax is
code=<authorization_code provided after a user consents>
grant_type=authorization_code
client_id=<6 character client ID that you provided me>
redirect_uri=<redirect_uri>
code_verifier=<code_verifier>
You should never post your client secret in the HTTP request unless you've properly built the Basic token.
Please check your syntax and see if you can make these changes.
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

09-09-2020 10:52
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

09-09-2020 10:52
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Yep, that's it. It's working now. Thank you very much!!!!
But I'm still wondering why this code was running without any problems since 2018...nvm

12-14-2020 00:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

12-14-2020 00:05
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hello. I have implemented as you answered here. But I still get error.
When I use postman, it is working. But when I use alamofire, I am getting error.
Please help me.

12-14-2020 08:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



12-14-2020 08:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @ksmks0921
What syntax and error message are you getting with alamofire?
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

