React Native - call restful API synchronously - android

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.

Related

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

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.

Secure android application made by ionic framework

I'm working on an android apps. I am using ionic framework. In some pages I need to get data from a web server and the result is an object json.
My problem is if some one arrives to GET the pages where I get the json data, one can fetch all my database data by changing the http request.
Is there any way that can improve security of my apps?
You should make some kind of authentication mechanism, for example, a token in the header, that way you know wether the user has access to that resource or not.
So when you make your request you can generate a configuration for that particular request.
Example:
var url = "http://yourserver.com/api/your/path";
var config = {
"headers": {
"Authorization": "Bearer someBearerFromTheServer"
}
};
$http.get(url, config);
The backend implementation for this to work depends on the language you use. Here google is your best friend.
A more advanced way to do this, is to use interceptors in the $http service and attach the token to the header in every request, but be careful, you should secure this so you won't send your credentials to every request you make (sometimes your app might need to request data from another server).
You can read more about $http services and its configurations in the $http service documentation.
Regards

Android: HttpUrlConnection uses POST to send request bodys (instead of GET)

I'm developing an Android application which communicates with (our own) API. It was meant to use the API in manipulative requests with the request method POST and at not-manipulative requests GET (as it should be in RESTful applications).
To authenticate or add parameters to the request, the HTTP request body has been used (in both GET and POST requests). (YES, it is possible and allowed to add a request body to GET requests per HTTP definition (see e.g. this post)). The post generally says, that it is possible to add a request body, but the server may not use it during the request.
The problem is, that the request method is always set to POST, no mather if I set it to GET anywhere during the connection configuration, even if the getRequestMethod does return GET after setting it to GET via setRequestMethod("GET").
The android application uses the HttpsURLConnection (which is an extended class from HttpURLConnection, so it should behave similary).
By calling these methods, a request body will be attended:
https.setDoInput(true);
OutputStream os = https.getOutputStream();
os.write(outputInBytes);
os.close();
And by calling https.setRequestMethod("GET"), the request method should be set to GET.
After a little investigating, the line OutputStream os = https.getOutputStream(); sets the request method to POST, afterwards I set it to GET again and it remains GET till the end of the connection (as returned by https.getRequestMethod())
But in the end the server receives the request with the request method POST.
So my specific questions are:
Is there a possible workaround / solution for this problem?
Is it really that bad to add a request body to a GET request?
Currently I have just set all requests to POST, so there is no problem with it (and I wouldn't have a problem to leave it this way, but for several reasons I would like to know for sure that there is no other way to fix this problem)
Edit: The documentation of the getOutputStream() method says:
The default request method changes to "POST" when this method is called.
By default the HttpURLConnection is a GET Method (getDoInput() is true by default).
If you use setDoOutput(true) it will become a POST method.
If you need another method (PUT, DELETE, etc...) then you will use setRequestMethod(string).
And of course you have to select the method you want before the connect() method

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.

How to invalidate/force update of cache route at next request with Retrofit and OKHttp?

I'm using Retrofit with OKHttp client for caching responses from a JSON API.
This works nicely.
However, if I take an action on the device which causes the data to update on the server I need a way to 'invalidate' a particular route in order to ensure that next time a request is made for this data, it is fetched from the server again rather than the now outdated cached version.
Currently, I've worked around this by explicitly calling the new route with a "no-cache" flag in the Cache-Control header of the request, but this forces me to download the new data before it is needed, potentially multiple times if multiple actions are taken, just to keep the cache up to date.
Is there a way I can mark a route / method in my retrofit/OKhttp client as cache expired, requiring a mandatory update over the network the next time it's requested?
With retrofit2 and OkHttp3 you can force a new response by adding a Cache-Control header to your API method definition parameters:
#GET("ws/something")
Something getSomething(#Header("Cache-Control") String cacheControl);
and then when calling you either supply null for a (maybe-)cached version or "no-cache" for a live version:
myApi.getSomething(forceRefresh ? "no-cache" : null);
This is now possible in OkHttp by using the Cache.urls() function. As the documentation says:
The iterator supports Iterator.remove(). Removing a URL from the
iterator evicts the corresponding response from the cache. Use this to
evict selected responses.
This was merged into master late December 2014 and seems to be part of these tags (releases): parent-2.4.0-RC1 parent-2.4.0 parent-2.3.0 parent-2.2.0
There isn't an API for this, but there should be one. Please open an OkHttp issue to report this.
It'll probably take a while for us to implement because we'll need to figure out what the best API for this is. Invalidating a single URL is straightforward. Invalidating a range of URLs (say square.com/cash/*) is more difficult because OkHttp's cache is currently organized by URL checksums. There's also ugly edge cases like what happens if the invalidated URL is currently being written to the cache.
To quote the official code sample using urls():
val urlIterator = cache.urls()
while (urlIterator.hasNext()) {
if (urlIterator.next().startsWith("https://www.google.com/")) {
urlIterator.remove()
}
}

Categories

Resources