How to get current Facebook access token on app start?
Solution 1
It must be so (this Facebook v4.1.2)
FacebookSdk.sdkInitialize(getApplicationContext());
mFacebookCallbackManager = CallbackManager.Factory.create();
mFacebookAccessTokenTracker = new AccessTokenTracker() {
@Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
...
}
};
mFacebookLoginButton = new LoginButton(this);
mFacebookLoginButton.setReadPermissions(Arrays.asList("public_profile", "email", "user_birthday"));
mFacebookLoginButton.registerCallback(mFacebookCallbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
...
String token = loginResult.getAccessToken().getToken()
...
}
@Override
public void onCancel() {
Lo.d("Facebook login - the user did not give permission");
}
@Override
public void onError(FacebookException e) {
e.printStackTrace();
}
});
Solution 2
@Gokhan Caglar is right, the access token is null if the Facebook Sdk is not done initializing. So what about this?
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FacebookSdk.sdkInitialize(this /* applicationContext */);
setContentView(R.layout.activity_getting_started);
callbackManager = CallbackManager.Factory.create();
if (AccessToken.getCurrentAccessToken() == null) {
waitForFacebookSdk();
} else {
init();
}
}
private void waitForFacebookSdk() {
AsyncTask asyncTask = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
int tries = 0;
while (tries < 3) {
if (AccessToken.getCurrentAccessToken() == null) {
tries++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
return null;
}
}
return null;
}
@Override
protected void onPostExecute(Object result) {
init();
}
};
asyncTask.execute();
}
private void init() {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken == null || accessToken.isExpired()) {
// do work
} else {
// do some other work
}
}
Not the best solution in my eyes but waiting a bit for the Facebook Sdk might help.
Ralph Bergmann
Updated on June 05, 2022Comments
-
Ralph Bergmann almost 2 years
On app start I need to know if the user is logged in or not to show a login page or not.
My first try was to call
AccessToken.getCurrentAccessToken()
, but this doesn't work, see https://stackoverflow.com/a/29854249/1016472My 2nd try was to use the AccessTokenTracker but this doesn't work too. To use the AccessTokenTracker I have to initialize the Facebook SDK first. But during this initialization the access token is send to the tracker. The tracker isn't created at this time and can't receive the token.
My 3rd try was to create my own AccessTokenTracker which looks like the original one. I created and registered it before I initialize the SDK. And now my tracker get's the token during this SDK initialization process.
With this knowledge I open a bug report at Facebook with the questions:
- Why the AccessTokenTracker depends on the initialized SDK. I think this is a mistake.
- What is the right way to see if a user is logged in or not on app start.
The answer from Facebook:
This doesn't look like bug. The AccessTokenTracker ::onCurrentAccessTokenChanged should let you know when the class has received a token.
I know that this is not working. And now I know there is no bug.
But how to solve my problem?
This doesn't work:
FacebookSdk.sdkInitialize(getApplicationContext()); mAccessTokenTracker = new AccessTokenTracker() { @Override protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) { Timber.i("AccessTokenTracker oldAccessToken: " + oldAccessToken + " - currentAccessToken: " + currentAccessToken); } };