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

grant Type missing

 After struggling almost for 3 weeks I am still at grant Type missing. I am creating a app in Swift want to access user steps and add user steps Please help. 

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        print("\(url)")
        
        var parameter = Dictionary<String, AnyObject>()
        var headers = Dictionary<String, String>()
       
        parameter["grant_type"] = "authorization_code"
        parameter["client_id"] = "MYCLIENTID"
        parameter["code"] = "\(url.query!)"
        
        print(parameter)
        
        
        do {
            let jsonData = try NSJSONSerialization.dataWithJSONObject(parameter, options: NSJSONWritingOptions(rawValue: 0))
            let jsonString = NSString(data&colon; jsonData, encoding: NSUTF8StringEncoding)! as String
            if let url = NSURL(string:"https://api.fitbit.com/oauth2/token") {
                let mutableRequest = NSMutableURLRequest.init(URL: url)
                mutableRequest.HTTPMethod = "POST"
                mutableRequest.setValue("Basic MyBASE64ECODEDTHING", forHTTPHeaderField: "Authorization")
                mutableRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
                
                let session = NSURLSession.sharedSession()
                
                let task = session.uploadTaskWithRequest(mutableRequest, fromData&colon; jsonString.dataUsingEncoding(NSUTF8StringEncoding), completionHandler: uploadResponse)
                task.resume()
            } else {
                print("Unable to create NSURL")
            }
        } catch {
            
        }
 
    func uploadResponse(data&colon;NSData?, response: NSURLResponse?, error: NSError?) -> Void {
        guard error == nil else {
            print("Error near guard")
            return
        }
        let httpResponse = response as? NSHTTPURLResponse
        let status: Int = httpResponse!.statusCode
        
        if status != 200,
            let error = NSString(data&colon; data!, encoding: NSUTF8StringEncoding)
        {
            print("Error in JSON" + error.description)
            return
        }
    }
Best Answer
0 Votes
27 REPLIES 27

@MdSaleem wrote:

Your Documentation is very poor for FitBit API. For request a token. Almost all API have examples in common programming languagesSmiley Sad

 


Otherwise they would have to provide examples for most of the major languages, which means developers creating examples. There's a stick in the main forum that mentions that they won't be doing this, plus a mention in this thread and another thread in the last month.

 

OAuth2 isn't a definitive protocol like OAuth1 was, therefore its unlikely that two or more providers will share the exact same client implementaton. OAuth1 had the same authentication and authorization steps, but OAuth2 doesn't necessarily. Sometimes it's different and it really depends on how the provider wants clients accessing their data. Therefore, it's quite difficult to build a definitive list of OAuth2 examples in half-dozen or more languages because it changes, it's time consuming, and it doesn't translate across providers.

 

Did you solve the programming problem? Many developers in .net, java, swift, objc and php have got it working.

Best Answer
0 Votes

@MdSaleem wrote:

Your Documentation is very poor for FitBit API. For request a token. Almost all API have examples in common programming languages


While OAuth 2.0 is a "framework" and not a "protocol" like OAuth 1.0a, Fitbit's OAuth 2.0 implementation works "out of the box" with many OAuth 2.0 libraries. We referenced Google's, Box's, and many post-RFC and open source implementations in our implementation and have tested with many OAuth 2.0 libraries.

 

Given OAuth 2.0's ubiquity and our small team, we are focusing on supporting Fitbit API specific issues at this time. Nearly every language and application framework has an idiomatic way of making HTTP requests with OAuth 2.0. We will try to provide more examples in the future, but we will never be able to serve people as well as their preferred language's and framework's documentation.

 

The documentation clearly defines the HTTP requests that need to be made. We can't help you debug your application. You need to be able to examine the HTTP requests your application is making and compare them to what is documented.

Best Answer
0 Votes

Hey guy's thanks for support.

I request you please update oauthtutorial page for OAuth 2.0

https://dev.fitbit.com/apps/oauthtutorialpage

Best Answer
0 Votes

That only works for OAuth 1.0. You need a valid callback URI for OAuth 2.0 to work. For FitBit to be able to consume it, you need to provide a valid and accessible URI that can be found on the internet. Using debug=true in OAuth 1.0 you could work around it, as well as skip SSL checks (if using the PHP oauth1 lib).

 

@SunsetRunner and myself have created PHP providers for FitBit OAuth 2 that you can use for reference. We have both provided tutorials on our github READMEs.

 

Given that you aren't using PHP (Obj C), you should be able to break down the request flow into at least psuedo code and then work it into your prefered language. I know that there are request libraries that you can use to make it a bit easier for you to make the requests.

 

Is Swift an option for you to use? I know that if you use Swift, you can use Obj C with it as well (it compiles together, since Swift is just a layer on top of it).

Best Answer
0 Votes

Hi,

I am having a similar kind of issue but when I am trying to use OAuth2 for one of my ios application.

I am pretty sure I am setting the Authorization corretly and then using the authentication corretly and here is the response i get from server:

My Authorization request header are :

    "Accept-Language" = "en-US;q=1";
    Authorization = "Basic MjI3SE5DOjAwN*****";
    "User-Agent" = "****";

Then my paramerters to fitbit are:

    "client_id" = ***;
    "redirect_uri" = "example://";
    "response_type" = code;
    scope = activity;

base URL is : https://www.fitbit.com/oauth2/authorize

and I am getting this error:

Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo={com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x155f4e270> { URL: https://www.fitbit.com/login?redirect=%2Foauth2%2Fauthorize%3Fnull } { status code: 200, headers {
    "Cache-Control" = "no-store, no-cache, must-revalidate";
    "Content-Encoding" = gzip;
    "Content-Language" = "en-US";
    "Content-Type" = "text/html;charset=UTF-8";
    Date = "Mon, 11 Jan 2016 22:30:04 GMT";
    Expires = "Thu, 01 Jan 1970 00:00:00 GMT";
    Pragma = "no-cache";
    Server = "cloudflare-nginx";
    "Set-Cookie" = "fhttps=\"\"; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/, JSESSIONID=5FAD4DAE5C8C54329EA14FA236BE502E.fitbit1; Path=/; HttpOnly";
    Vary = "Accept-Encoding";
    "cf-ray" = "26341067ec7e0da9-SJC";
    "x-frame-options" = SAMEORIGIN;
    "x-ua-compatible" = "IE=edge,chrome=1";
} }, NSErrorFailingURLKey=https://www.fitbit.com/login?redirect=%2Foauth2%2Fauthorize%3Fnull, com.alamofire.serialization.response.error.data=<0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a0a0a0a 0a3c2144 4f435459 50452068 746d6c3e 0a3c212d 2d5b6966 206c7420 49452037 5d3e3c68 746d6c20 636c6173 733d226e 6f2d6a73 20696536 20696522 3e3c215b 656e6469 665d2d2d 3e0a3c21 2d2d5b69 66204945 20375d3e 2020203c 68746d6c 20636c61 73733d22 6e6f2d6a 73206965 37206965 223e3c21 5b656e64 69665d2d 2d3e0a3c 212d2d5b 69662049 4520385d 3e202020 3c68746d 6c20636c 6173733d 226e6f2d 6a732069 65382069 65223e3c 21....a lot of data stream i need to figure out how to decode it.

 

And When I start accepting the text/html I get this error:

Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

From the first try I guess the reponse has this string" https://www.fitbit.com/login?redirect=%2Foauth2%2Fauthorize%3Fnull" which is not clear to me why its happening.

 

My Thought is once this goes well I will be redirected automatically to safari where I will be presented with the authenticaion page and I will enter my login details and then redirect to my urlSheme which will launch my app from safari and then the response will contain the access token that i can use further for api calls.

Please help me as I am trying to figure this out since morning.

 

I also tried this from Postman app and I get a very long "Access Token data as follows:"

<!DOCTYPE html> <html> <head> <meta charset"utf-8"/> <title>Postman</title> <script type="text/javascript" src="js/config.js"></script> <link rel="stylesheet" type="text/css" href="css/preload.css"/> <link rel="stylesheet" type="text/css" href="css/custom-theme/jquery-ui-1.9.2.custom.min.css"/> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/> <link rel="stylesheet" type="text/css" href="css/bootstrap-modal.css"/> <link rel="stylesheet" type="text/css" href="css/nanoscroller.css"/> <!--<link rel="stylesheet" type="text/css" href="css/bootstrap-editable.css"/>--> <!-- Xml tree --> <link rel="stylesheet" type="text/css" href="css/xmltree.css" /> <!-- Json Tree --> <link...

 

Regards..

Amit

Best Answer
0 Votes

Your authorization request needs to be a post and you need to specify the content-type as application/x-www-form-urlencoded:

 

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

The same needs to be done when refreshing tokens. 

Best Answer
0 Votes

Thanks for the reply.

It seems like the url that you have sent in the exmple is for getting the user data via api.fitbit.com once the authenticatiopn is done and we get the token. Please correct if I am wrong.

 

And FYI, my requests are POST.

Best Answer
0 Votes

The example was from the authorization documentation.

 

Your error was quite specific, so if you change your Content-Type header it should succeed. You don't have to worry about setting the accepts header when making an auth request since the browser is redirected, but for a refresh and authenticated requests against the API you need application/json as your accept (optional).

 

FYI: All requests except the initial auth request are returned as JSON.

Best Answer
0 Votes