Use RxJava in queue-like manner and pause/start queue - android

I'm trying to use RxJava in my Android application, along with Retrofit, to interact with a RESTful API.
In my Android app I sent out a number of requests at various UX events. If one of the request returns an 'Invalid Token' error, I want to pause any other requests that get queued before they start so that I can renew the user's token, and then resume the paused requests.
Is this possible using RxJava? I'm just learning the library and am having trouble finding this functionality.
Thanks,

If these requests are sent in parallel, then you will likely get multiple "Invalid Token" errors. You would want to refresh the token for only the first instance of the error. To pause requests while the token is being refreshed, think about the source of the valid token being an observable.
Let's assume you have a network handling class that has methods:
Single<Response> makeNetworkRequest(Request request) { ... }
Single<Boolean> getToken() { ... }
It is implemented such that a value is emitted when a token is available, but otherwise waits until the token is refreshed.
Then, your observer chain will look something like:
observerChain
.flatMapSingle(request -> networkHandler.makeNetworkRequest(request)
.retryWhen(error -> error.flatMapSingle(e -> networkHandler.getToken()))
...
The retryWhen() operator recovers from the error by providing an observable that, when non-empty, will resubscribe to the upstream observable, in this case, the makeNetworkRequest().
Since you don't show any of your code that you are trying to adapt, you will have to make adjustments to the code above to get it to work with your application.

Related

Retrofit Authenticator Refresh Token

I’m looking for a similar solution that can handle multiple requests that occur in parallel. Wouldn’t this solution refresh a token for each request that received 401 ? So if for instance, I enter a screen and issue 5 different requests, each one will receive a 401 and each one will issue a refresh token request in that runBlocking block. Is there an elegant way of stopping 4 out of the 5 requests and return to them with the result of the refresh that occurred in the first request?

Refresh access token before it expires using refresh token

I am working on an application, which uses OAuth - Token based authentication.
This is how the flow looks like, considering we have the access and refresh token.
Api call -> intercepter appends access-token -> api returns 200
Api call -> intercepter appends expired access-token -> api returns
401 -> intercepter refreshes token using refresh token ->
interceptor retries same req -> returns 200
Api call -> intercepter appends expired access-token -> api returns
401 -> intercepter refreshes token using refresh token(refresh token
is also expired) -> prompt guest to sign-in -> guest signed-in ->
retry request
This all works great and fine - I am considering to optimise it a bit i.e i don't want to call api and wait for 401 to return.
Instead check for token expiration beforehand, get the new access token and then call the api with valid token.
This approach of calculating the expiry of token using android system time might work - but can be misused sometimes when user changes the android time.
Wondering if there a better solution to avoid the expiry issue of time based on android system time.
Even if you add such a check in your code, you will still need that flow you presented in the question (so catching 401s and refreshing tokens accordingly). This is because, as you noticed, time settings on the client device can be changed, or there might be a slight clock skew between the client and the server (so no intentional tampering with time settings).
The approach where you check for expiry before the API call will work only if you have access to the expiration time of the access and refresh tokens. So either you received that information together with tokens and persisted it, or JWTs are used and you can easily check expiration.
Personally, I wouldn't add such a check unless there is some strong argument for it (e.g. you know that your app will be mainly used in remote locations with slow connections and you want to limit traffic to a minimum, etc.). The flow that you presented is a common one and works just fine.

React Native - call restful API synchronously

I know that React Native uses JS way of doing things ie making function calls asynchronous. So this also applies to API "fetch" function. However, for some reason, I need to make API "fetch" synchronous.
This is what I want to do. The app has a listing of items. It has to loop through the items and for each of them, I need to construct the URL and then call "fetch" based on constructed URL to get the response (eg if I have 5 items, it would call the API 5 times, where each URL called has different parameters). Once I have successfully received responses for all of the listing items, then I need to do something else, such as updating some state (the state is dependent on having all of the responses returned).
Note that I have no control over the backend ie unable to change the URL side to have batch calls instead.
Question is, how do I make sync call in React Native?
You can call synchronously by using XMLHttpRequest object.
var request = new XMLHttpRequest();
request.open('GET', 'https://mywebsite.com/endpoint.php', false); // third parameter FALSE makes Synchronous HTTP request
request.send(null);
if (request.status === 200) {
console.log(request.responseText);
}
or
you will get many npm modules that will provide synchronous api call.
i hope this will help you.

What is the best way to add and check authorization token?

I am implementing an android application which will validate user details against the server and stores the return token. For subsequent requests it should send the token along with each request. Here are some of the points I need to consider.
I am using Retrofit 2 library to send http requests to the server
The token will be generated by JWT library and sent back to the client
If the token is not present or invalid or expired, the server will throw 400/401 error
Design
The landing page of android app is not login protected so that user can see the app before using his credentials
Once he is on MainActivity, any requests to other screens require authentication. So all other activities will check for token and redirect to login activity.
In case any response received from server has 400/401 header, it should also redirect to login page.
Considering the above requirements, I tried to add an interceptor in Retrofit service generator class which which will be executed on every request/response.
Problem
The interceptor is executed for every request not just once per activity. i.e. it is opening n number of logic activities if there are n number of async calls in the main activity (because no token will be present for all those requests).
Can someone help me in identify:
If there is a better design that can avoid such problem or
Is there any way to suspend main activity until login is completed and then resume it.

Android In App Billing v3 Server Verification

I have in Google in app billing set up in my app using the IabHelper classes from the trivialdrive sample app. I can successfully purchase items, and now I'm trying to implement server side verification.
I see in Security.java that there is a verifyPurchase method.
https://code.google.com/p/marketbilling/source/browse/v3/src/com/example/android/trivialdrivesample/util/Security.java
I want to replace that with a call to my server that will do the verification on the server vs on the client device. I have my endpoint set up and working.
I'm stuck at how to call my endpoint and have verifyPurchase return true or false based on the response. I currently use Volley which makes async calls. I can get my endpoint's response in Volley's success callback. But since that network call is async, I'm not sure how to return true or false in verifyPurchase based on that call's response. I'm a java n00b :)
Create an interface call that in response of the async call of volley use that. Implement that interface in that class where you need your verifyPurchase() return. Override that interface and process the response.

Categories

Resources