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

Redirect url - need URGENT advice..

ANSWERED

 

Hello, I have an issue with the redirect_url on Android.. 

User is directed to the Authorization Page in Chrome Custom Tabs, when I click "agree", user is not redirected back to application.. 

 

What are the rules and expectancies regarding redirect_url for FitBit API?

I find the documentation on the website very unclear.. 

 

I have already set callback_uri in many different ways, with different outcomes:

 

Local Page with Auth Code, no redirect because not specified:

http://locallhost.com/

 

Error Not Found:

- http://locallhost.com/callback

- http://locallhost.com/redirect

 

What should I use to test locally? 

 

Oops it it not you, it is us.. 

- https://www.fitbit.com

 

Setting in the Application Page are correct. 

Settings in the Manifest are the following, adapted per redirect.. 

 

<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.locallhost.com/redirect"
android:scheme="http"/>
</intent-filter>

 

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

The URL your calling is the same format as mine, although since my app is web based I have to include the callback_url. So my initial thought is there is a problem with the Chrome Tab talking to your app after you finish logging into Fitbit - since its Fitbit, not your app, that tells Chrome were to redirect you too after a successful login.

 

http://www.locallhost.com is a valid web page, I can open it up in Firefox and I get a valid web page. But both www.locallhost.com/callback and www.locallhost.com/redirect return 404 errors. So my initial thought is the Chrome Tab is getting confused and loading the webpage rather than sending you straght back to you own app. Since http://www.locallhost.com is valid Chrome loads that page before sending you back to your own app but when the other two address return 404 errors it fails and never actually returns you too your app.

 

Could you try changing your android:scheme from "http" to something unquie to your app like "niels" and the android:host from "www.locallhost.com" to "fitbitcallback"?

 

Since that would turn your callback url into 'niels://fitbitcallback' Chrome would have ignore the link, hopfully sending it straight to your app instead of trying to load the page. You will however need to go into https://dev.fitbit.com/apps and update your registered app's callback url though

 

If this doesnt work let me know. I dont have an Android development enviroment setup but I'll happily do that tomorrow to test out a few other ideas - although I've not written for Android in years (think Froyo) and will take me an hour or so to catch up - but I'll happily stick around till we get this working for you

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App

View best answer in original post

Best Answer
65 REPLIES 65

Hi Niels

 

I've been programming against the Fitbit API for a while now, although in PHP not Android - so please forgive that I can't give you a detailed answer.

 

In Andriod I think you need to setup an app Intent and set your callback URL to be your app's defined URI schema, also called a "deep link". I found this old post on StackOverflow that might point you in the right direction Android Chrome custom tabs / Fitbit web API won't redirect if app is already authorized. (OAuth2.0)

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer

I am using Chrome Custom Tabs, Intent Filter is set up together with Application Settings at API EndPoint and callback_url.. None of the above callback_url's is working properly. 

 

I do not understand why not.. 

Super frustrating since I have the functional specs written out and the data visualizations are practically ready based on another API.. 

 

Any idea? 

 

Thanks for the response! 

Best Answer
0 Votes

Do you mind sharing your intent-filter XML and customTabsIntent.launchUrl() lines so I can see the URL your sending to the Chrome tab?

 

Please blank out your 'client_id' though

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

My url (blanked out client_id), callback_url is not included since I only have 1 this is optional.. 

I have tried including it, did not work either, same result.. So I decided to leave it out since it is optional because I only have 1.. 

https://www.fitbit.com/oauth2/authorize?response_type=code&client_id=xxxxxx&scope=activity%20heartrate%20location%20profile%20sleep

 

My Intent Filter in the Manifest

<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.locallhost.com/callback"
android:scheme="http"/>
</intent-filter>

 

Good to know: 

www.locallhost.com brings me to the local page, with the authorization code - doing what it's supposed to.. 

www.locallhost.com/callback OR www.locallhost.com/redirect gives me an error message "error not found".. 

Best Answer
0 Votes

The URL your calling is the same format as mine, although since my app is web based I have to include the callback_url. So my initial thought is there is a problem with the Chrome Tab talking to your app after you finish logging into Fitbit - since its Fitbit, not your app, that tells Chrome were to redirect you too after a successful login.

 

http://www.locallhost.com is a valid web page, I can open it up in Firefox and I get a valid web page. But both www.locallhost.com/callback and www.locallhost.com/redirect return 404 errors. So my initial thought is the Chrome Tab is getting confused and loading the webpage rather than sending you straght back to you own app. Since http://www.locallhost.com is valid Chrome loads that page before sending you back to your own app but when the other two address return 404 errors it fails and never actually returns you too your app.

 

Could you try changing your android:scheme from "http" to something unquie to your app like "niels" and the android:host from "www.locallhost.com" to "fitbitcallback"?

 

Since that would turn your callback url into 'niels://fitbitcallback' Chrome would have ignore the link, hopfully sending it straight to your app instead of trying to load the page. You will however need to go into https://dev.fitbit.com/apps and update your registered app's callback url though

 

If this doesnt work let me know. I dont have an Android development enviroment setup but I'll happily do that tomorrow to test out a few other ideas - although I've not written for Android in years (think Froyo) and will take me an hour or so to catch up - but I'll happily stick around till we get this working for you

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer

I just seen your other post in 'Frustration getting Fibit API authenticating & working with Xamarin forms via (iOS & Android)'

 

The redirect_url doesnt have to be hosted on a real website. So you want have to buy a domain name for it to work. Instead the URL can be anything you like, as long as your users can access it. In one of my apps the redirection url is simple http://127.0.0.1 and since this address is always the local machine it works fine since when I log in I can access it.

 

This is why I think the suggestion above might work, since the updated intent-filter is telling Android your app can handle this URL using it as a redirect_url should work correctly

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer

One step further, I get a redirect but I do not get my code back..

So now the redirect is working but my code is not there.. 

 

Scanner in = new Scanner();
System.out.println(in.hasNextLine()); FALSE..

 

Then I can continue with the code.. 

Best Answer
0 Votes

Did you have to log into Fitbit when the Chrome tab opened or were you already logged in, from a previous test? There appears to be a problem with how Fitbit handles redirections from already logged in users

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

No, in both cases - logged in and not logged in - I am immediately taken to the FitBit Authorization Page.. 

Best Answer
0 Votes

Can you try this code in your return actvity class:

	String string;
	
	@Override
	protected void onNewIntent(Intent intent) {
		string = intent.getDataString();
	}
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		onNewIntent(getIntent());

		Set<String> args = string.getQueryParameterNames();
		String returnedCode = uri.getQueryParameter("code");
		
		System.out.println(returnedCode);
	}

This was writen from memory so it might not be perfect code

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

I need some time to properly understand this before I put it in my code.

Will try to do this tomorrow.. 

I will let you know if it works or not. 

 

Thank you very much for your time! 

You are of great help to me! 

 

Niels

Best Answer
0 Votes

No problem, I hope it works for you. The intention with the code is the assumption that Chrome Tab is returning you to you app with a URL like niels://fitbitcallback?code=12345

 

onNewIntent() should take the full URL and store it in 'string'. getQueryParameterNames() is supposed to get anything after ? and store it in a String set you can then using getQueryParameter() to get the code permeter.

 

That is the intention anyway, let me know how you get on

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

I did as you said..

 

String string;
URL uri;

onNewIntent(getIntent());

Set<String> args = string.getQueryParameters();
String returnedCode = uri.getQueryParameter("code");

System.out.println(returnedCode);

 .getQueryParameters() is not recognised for string..

.getQueryParameter() seems ok for uri.. 

Best Answer
0 Votes

Sorry @NielsWearables it must have been late last night - I forgot to actually create the Uri object from string.

 

 

    String string;
    Uri uri;
    
    @Override
    protected void onNewIntent(Intent intent) {
        string = intent.getDataString();
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        onNewIntent(getIntent());

        uri = Uri.parse(string);
        Set<String> args = uri.getQueryParameterNames();
        String returnedCode = uri.getQueryParameter("code");
        
        System.out.println(returnedCode);
    }

 

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

Yes was quite late, as usual 🙂

 

Set<String> args = uri.getQueryParameterNames();

The compiler can't find the method "getQueryParameterNames()" and starts to behave strangely. Now it loads 2-3 times before it ends up on my activity. 

 

On top of that, I get a NullPointerException on line

uri = Uri.parse(string);

 So no string found to parse.. 

Best Answer
0 Votes

Well thats frustrating Smiley Frustrated

 

What API level are compiling against? According to the docs getQueryParameterNames was added in API level 11

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

Another example I found has a slighlty updated onNewIntent function, could you try this?

 

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, intent.toString());
        string = intent.getDataString();
    }

 

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes

API level 17.. So it should be included..

 

I changed the to "string" to "uri", now method is recognised, but still error..

Still NullPointerException on line 

uri = Uri.parse(string);

 

 Now I have..

onNewIntent(getIntent());
uri = Uri.parse(string);
Set<String> args = uri.getQueryParameterNames();
String returnedCode = uri.getQueryParameter("code");
System.out.println(returnedCode);

 

So probably still an error in the onNewIntent() method.. 

Best Answer
0 Votes

Did Log.d(TAG, intent.toString()) put anything in the log files?

Ionic & Aria, Blaze (retired), Alta (retired), Surge (retired), Charge HR (retired), One (retired), Classic (retired) | Microsoft Surface | Google Pixel 2XL Android FitBit App
Best Answer
0 Votes