Reputation: 63
I have to receive a token from an API, store it in shared preferences and make a call to the API only if the token has expired. The token expires after 200000 seconds. Basically I'm try to follow these instructions:
However the first API call is made even before the token is generated and null is passed as token, then the token is generated and stored in Shared Preferences. So it just doesn't work the first time, and then works. Is there a problem with using if conditions and asynchronous Retrofit calls.
Here's the function I used to create a token
public void getToken(){
Credentials credentials=new Credentials("public_user","public_pass");
Call<Authentication> call=service.getToken(credentials);
call.enqueue(new Callback<Authentication>() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onResponse(Call<Authentication> call, Response<Authentication> response) {
if (response.body().getCode() != 0) {
token = response.body().getDocument();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
SharedPreferences.Editor editor=preferences.edit();
editor.putString("token",token).commit();
tokenExpires=Instant.now().plus(Duration.ofSeconds(200000));
long millis=tokenExpires.toEpochMilli();
editor.putLong("token_expiry_time",millis).commit();
String this_token=preferences.getString("token",null);
}
}
@Override
public void onFailure(Call<Authentication> call, Throwable t) {
}
});
}
And here's how I am calling this function and using it to call the API
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
service = ApiClient.getClientStats().create(ApiInterface.class);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
String retrievedToken = preferences.getString("token",null);
long token_expiry_time=preferences.getLong("token_expiry_time",0);
if(retrievedToken==null || token_expiry_time==0 || token_expiry_time<=Instant.now().toEpochMilli()) {
getToken();
retrievedToken=token;
}
else {
Call<Stat> call = service.getMapData("Bearer " + retrievedToken);
call.enqueue(new Callback<Stat>() {
@Override
public void onResponse(Call<Stat> call, Response<Stat> response) {
}
}
@Override
public void onFailure(Call<Stat> call, Throwable t) {
}
});
}
Upvotes: 0
Views: 241
Reputation: 149
When you call getToken() retrofit runs it on another thread. While this is happening the main thread continues its execution in the if statement and assigns null to retrieveToken as at that time token is null, that is the reason why you have the first null. Then retrofit completes it exec and sets the shared preferences. You can use LiveData to observe for the result before making other queries.
Upvotes: 1