Ti.Network.createHTTPClient async - android

I have the need to download data from a web server at startup of the app . The data is to be retrieved from a 50 http addresses . The problem that I load the page of the app before it has completed the recovery operation via http request of titanium . Do you have any suggestions?
function doRequest(url, callback) {
var client = Ti.Network.createHTTPClient({
onerror: function (err) {
callback(err, null);
},
onload: function () {
try {
callback(null, JSON.parse(this.responseText));
}
catch (err) {
callback(err, null);
}
}
});
client.open('GET', url);
client.send();
}

use promises.
https://github.com/kriskowal/q
Look at documentation on all or sequences
return Q.all([
download(url1),
download(url2)
...
]);

Related

what should I do to solve flutter socket_io_client client automatic dissconnect?

I use socket_io_client to connect to a server socket. it works fine but after getting the first response it dissconnects and I should connect it again and again. It doesnt listen to the sever infinintly. here is my code
initSocket(String msg,String userStr) async {
if(socket!=null){
await loginToServer('$userName\n');
}else{
socket = await Socket.connect(socketIpAddress, 1500);
print('Connected to: ${socket!.remoteAddress.address}:${socket!.remotePort}');
await loginToServer('$userName\n');
// listen for responses from the server
socket?.listen(
// handle data from the server
(Uint8List data) {
final serverResponse = String.fromCharCodes(data);
print('Server: $serverResponse');
if(serverResponse.contains('hello')){
sendMessage(msg, userStr);
}else{
ParserSocket().getMessage(serverResponse.substring(9), serverResponse.substring(3,9), SentType.Internet, false, ctx);
}
},
// handle errors
onError: (error) {
print(error);
socket?.destroy();
},
// handle server ending connection
onDone: () {
print('Server left.');
socket!.destroy();
},
cancelOnError: false
);
}
}
Future<void> sendMessage(String message,String userName) async {
print('Client: $msg');
socket?.write(msg);
}
I checked onDone() method but no result

Fetch DELETE method on Android (React Native)

I make several requests from a React Native app to an API. Every request works fine both on iOS and Android except the DELETE method that does not work on Android. The call is correctly made, it goes through the API and the objects are deleted. But instead of getting the response, the call falls under the catch statement with [TypeError: Network request failed]. This does not happen in iOS.
Some people with the same problem were missing 'Content-Type': 'application/json' on the request headers which is not my case.
This is happening both locally, in testing and production stages (using an ip instead of localhost will do nothing).
The request is also successfully performed in Postman.
What can it be?
React Native 0.63.5
export const deleteApi = async (api: string, body?: any) => {
const userResponse = await getUserCredentials();
const authState = await getAuthState();
let response = await fetch(api, {
method: 'DELETE',
headers: await getHeaders(userResponse, authState),
body: JSON.stringify(body)
});
if (response.status === UNAUTHENTICATED_CODE)
response = await interceptor(response, userResponse, {
api: api,
method: 'DELETE',
body: body
});
return response;
};
leaveClass = async (
uuid: string,
onSuccess: () => void,
onFailure: (error: string) => void,
) => {
this.setLoading(true);
try {
const api = LEAVE_CLASS_API_PREFIX + uuid + LEAVE_CLASS_API_SUFFIX;
const response = await deleteApi(api);
if (response.status === SUCCESS_STATUS_CODE) {
onSuccess();
}
else {
const jsonResponse = await response.json();
if (jsonResponse.detail) onFailure(jsonResponse.detail);
else onFailure(translations.SOMETHING_WENT_WRONG);
}
} catch (error) {
console.log('leaveClass error: ', error);
}
this.setLoading(false);
};
You can use a network plugin for Flipper (https://fbflipper.com/docs/setup/plugins/network/), copy your request from it as a curl, and try to perform it from your terminal or postman. If it has the same error, the problem is not in React Native.

status: -1: There was an error with the request: no protocol:

I'm trying to do an HTTP request on an android emulator, I built with ionic and compiled with capacitor.
I'm using the HTTP module from #ionic-native/http/ngx. I have a per-existing interceptor that I used when I was making requests using the HttpClient from #angular/common/http. This is what that interceptor looks like:
export class InterceptorService implements HttpInterceptor {
protected apiUri = environment.API_URL;
constructor(
private authSvc: AuthService,
private toastCtrl: ToastController
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const url = this.apiUri + req.url;
const token = this.authSvc.getStorageToken();
if (token) {
req = req.clone({
url,
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
}
return next.handle(req).pipe(
map((event: HttpEvent<any>) => {
return event;
}),
catchError( (err: HttpErrorResponse) => {
let errMessage = err.error.message;
if (err.error.title) {
errMessage = err.error.title;
}
if (!errMessage) {
errMessage = err.error;
}
this.presentToast(err.status, errMessage);
return throwError(err);
})
);
}
async presentToast(status: number, message: string) {
const toast = await this.toastCtrl.create({
message,
buttons: ['OK']
});
await toast.present();
}
}
My auth-service:
/* service request to get a toke */
getAuthToken(model: IGetTokenModel) {
return this.http.post('/user/token', model, {});
}
The environment.API_URL is the url to my API on my local machine.
I'm guessing the no protocol means I'm posting data to /user/auth instead of the full which includes the hostname. But I'm not sure of this. However, if that were the case, how would I refactor my interceptor so that it works as expected with the #ionic-native/http/ngx?
Finally have this sorted. I was pointing to localhost inside the emulator. Turns out that requests made inside the emulator have to point to http://10.0.2.2:PORT.
I suppose localhost in a sense still point to the emulator itself.

How to pass an object from android app to a firebase cloud function to complete Paypal payment functions?

I am using firebase cloud functions as serverside for Paypal payment. Documentations are not obvious to understand.
when I am trying to send an object from android app to firebase cloud functions, nothing has happened. I think I added it wrong. so how can I pass an object from android app to the function??
public void payout(String PayerID,String paymentId) {
// Create the arguments to the callable function.
JSONObject postData = new JSONObject();
try {
postData.put("PayerID", PayerID);
postData.put("paymentId",paymentId);
} catch (JSONException e) {
e.printStackTrace();
}
mFunctions
.getHttpsCallable("payout")
.call(postData)
.continueWith(new Continuation<HttpsCallableResult, Object>() {
#Override
public Object then(#NonNull Task<HttpsCallableResult> task)
throws Exception {
return null;
}
});
}
///////////////////////////////////////////
exports.payout=functions.https.onRequest((req,res)=>{
const sender_batch_id = Math.random().toString(36).substring(9);
const payReq=JSON.stringify({
sender_batch_header: {
sender_batch_id: sender_batch_id,
email_subject: "You have a nice payment"
},
items: [
{
recipient_type: "EMAIL",
amount: {
value: 0.90,
currency: "USD"
},
receiver: "amrmahmoudM#app.com",
note: "Thank you very much.",
sender_item_id: "item_3"
}
]
});
paypal.payout.create(payReq,(error, payout)=>{
if (error) {
console.warn(error.res);
res.status('500').end();
throw error;
}else{
console.info("payout created");
console.info(payout);
res.status('200').end();
}
});
});
exports.process = functions.https.onRequest((req, res) => {
const paymentId = req.body.paymentId;
var payerId = {
payer_id: req.body.PayerID
};
return paypal.payout.execute(paymentId, payerId, (error, payout) => {
if (error) {
console.error(error);
} else {
if (payout.state === 'approved') {
console.info('payment completed successfully, description: ',
payout.transactions[0].description);
const ref=admin.firestore().collection("Users").doc(payerId);
ref.set({'paid': true});
} else {
console.warn('payment.state: not approved ?');
}
}
}).then(r =>
console.info('promise: ', r));
});
The problem comes from the fact that in your Android app you call an HTTPS Callable Function (via mFunctions.getHttpsCallable("payout")) but your Cloud Function is not an HTTPS Callable Function but a "simple" HTTPS Function.
HTTPS Callable Functions are written like:
exports.payout = functions.https.onCall((data, context) => {
// ...
});
while HTTPS Functions are written like:
exports.payout = functions.https.onRequest((req,res)=> {
// ...
})
So you should adapt the code of your Cloud Function according to the documentation: https://firebase.google.com/docs/functions/callable
Note that another option could be to write to the database (Real Time database or Firestore) and trigger the Cloud Function with an onWrite or onCreate trigger. The advantage of this approach is that you directly save the information of the payment in the database.

Android HTTP errors when using POST with Appcelerator

I'm using Appcelerator to build an app for both iOS and Android.
Part of the app requires HTTP POSTs to an API.
This works great on iOS, but fails on Android, giving me this error in the process...
[ERROR] : TiHttpClient: org.apache.http.client.HttpResponseException: Not Acceptable
I understand there may be a few differences in how Android handles these calls, but I'm not exactly sure what I need to change in order for them to work.
Here is one of the calls I'm making.
Any pointers on what i could be doing wrong?
function doRegister() {
// check to see if we already have a username saved
if (!Ti.App.Properties.getString('userEmail')) {
var userEmailfromBox = Ti.App.Properties.getString('userEmailfromBox');
var HashedEmail = Ti.Utils.sha256(userEmailfromBox);
var registerData = {
"account": {
"name": userEmailfromBox,
"mail": userEmailfromBox,
"pass": HashedEmail,
"field_user_type": {
"und": "xxxxx"
}
}
};
var registration = Ti.Network.createHTTPClient({
onload: function() {
// handle the response
Ti.API.info(this.responseText);
// need to save this email so we don't keep registering the user
Ti.App.Properties.setString('userEmail', userEmailfromBox);
// then we need to load the next step
doLogin();
},
onerror : function(e) {
Ti.API.info('Registering: ' + e.error);
//alert('error');
// then we need to load the next step
//doLogin();
}
});
registration.open('POST', 'https://www.myurlredacted.com');
// change the loading message
//loaderWheel.message = 'Creating User';
loaderWheel.message = 'Uploading Your Photos';
// show the indicator
loaderWheel.show();
// set the header for the correct JSON format
registration.setRequestHeader("Content-Type", "application/json; charset=utf-8");
// send the data to the server
registration.send(JSON.stringify(registerData));
} else {
// user is already registered, so skip them onto the next step
Ti.API.info('user already registered');
// then we need to load the next step
doLogin();
}
}
I just ran the following code based on yours:
var url = "http://requestb.in/1iuahxb1";
var registerData = {
"account": {
"name": 'userEmailfromBox',
"mail": 'userEmailfromBox',
"pass": 'HashedEmail',
"field_user_type": {
"und": "xxxxx"
}
}
};
var registration = Ti.Network.createHTTPClient({
onload: function () {
// handle the response
Ti.API.info(this.responseText);
},
onerror: function (e) {
Ti.API.info('Registering: ' + e.error);
}
});
registration.open('POST', url);
// set the header for the correct JSON format
registration.setRequestHeader("Content-Type", "application/json; charset=utf-8");
// send the data to the server
registration.send(JSON.stringify(registerData));
It runs without errors and the requestb.in recieves the post:
http://requestb.in/1iuahxb1?inspect

Categories

Resources