Hey I am trying to get Fitbit API oauth2/token access but its throwing the following error
There was an issue setting up your call.
Raw response for the API
Status code 400
{"errors":[{"errorType":"invalid_request","message":"Missing 'grant_type' parameter value. Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}
This may just be me but 9/10 times I create the oAuth flow manually instead of using bubbles built in oauth2 feature. It very rarely works as you want in my experience and most APIs I’ve needed to do it on (Google, ticktock, outlook, etc) all tend to work better when done manually.
Manually: button click to go to auth URL. Watching redirect URL for code or token, saving that and storing refresh times and refreshing when necessary.
Can you share screenshot? The original one have some issues related to use of auth + use of manual auth. This is not compatible. + Authorize url was not correct.
I’ve got the “code” for token by using “open an external website”, then call the API to get the token with that “code”, however, the response is always “Missing ‘grant_type’”.
I’ve tried the same parameter on FitBit OAuth2 Tutorial (OAuth 2.0 Tutorial) and it worked there.
Thank you so much. I’ve tried as fast as I can, but still I could not succeed.
I could use the same code in FitBit Tutorial curl to receive the correct Token after I failed it on the Bubble API connector, so I could not figure out why Bubble API does not work.
Instead, I made a backend server side action just to get the token and it worked.
Thank you for your support.
Reference of my plugin server-side action code for anyone having the same issue
(FYI: I was trying to connect Fitbit account to the existing users who did not use Fitbit account to signup. If you want user to signup/login with Fitbit account, I guess Fitbit plugin will be a easier solution.)
:
async function(properties, context) {
const axios = require('axios');
const base64 = require('base-64');
// Extract properties
const redirectUri = properties.redirect_uri;
const code = properties.code;
// Retrieve Fitbit API credentials from context keys
const clientId = context.keys['FitBit Client ID'];
const clientSecret = context.keys['FitBit Client Secret'];
const authHeader = base64.encode(`${clientId}:${clientSecret}`);
// Prepare the request payload
const payload = new URLSearchParams();
payload.append('grant_type', 'authorization_code');
payload.append('redirect_uri', redirectUri);
payload.append('code', code);
try {
// Make the request to Fitbit API using axios
const response = await axios.post('https://api.fitbit.com/oauth2/token', payload.toString(), {
headers: {
'Authorization': `Basic ${authHeader}`,
'Content-Type': 'application/x-www-form-urlencoded'
}
});
// Return the required tokens and user ID with a success result
return {
result: true,
access_token: response.data.access_token,
refresh_token: response.data.refresh_token,
user_id: response.data.user_id
};
} catch (error) {
// Log the error details for debugging
console.error('Error fetching Fitbit token:', error.response ? error.response.data : error.message);
// Handle errors and return a failure result
return {
result: false,
error: error.response ? error.response.data : error.message
};
}
}