ionic3 error on android when calling GET HTTP - android

In Ionic3 I installed import { HttpClientModule } from '#angular/common/http'; and in my code I'm trying to call below url :
testHTTP(){
this.httpClient.get("https://api.upcitemdb.com/prod/trial/lookup?upc=5425016921463").subscribe(
data => {
console.log('Data : ', data);
this.lookup = data["items"][0].title;
}, err => {
console.log('Error : ', err);
this.lookup = JSON.stringify(err);
});
}
but every time it fails with :
{"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":null,"ok":false,"name":"HttpErrorResponse","message":"Http failure response for (unknown url): 0 Unknown Error","error":{"isTrusted":true}}
When I click on the button calling testHTTP on Chrome, I get a CORS error with this object (but I can deactivate CORS and get the real response).
How do you setup ionic http for the get to work please ?

You should use a XMLHttpRequest. And dont forget the Headers.
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.upcitemdb.com/prod/trial/lookup?upc=5425016921463", true);
//Really important to set this header
xhr.setRequestHeader("Access-Control-Allow-Origin","http://localhost:8100");
xhr.onreadystatechange = function() {
if(xhr.readyState == xhr.DONE) {
let ResponseFromRequest = xhr.response //Response from your request
}
}
xhr.send(null);

Related

Ionic BLE ble.write return null on ios

I'm using this plugin inside a ionic + stencil app
https://github.com/don/cordova-plugin-ble-central
I'm send a write command to a characteristic that support WRITE.
If I call ble.write on Android, the callback returns me OK
If I call ble.write on iOS, the callback returns me NULL.
in both cases, I can see on my peripheral device that the command has been sent correctly.
I connect to the device like this:
connectToDevice(device){
var toast = new utils();
let tclass;
let tmessage;
console.log('----connectToDevice----');
BLE.connect(device.id).subscribe(
peripheralData => {
this.device = peripheralData;
let connectBtn = document.querySelector('#connectBtn') as any;
console.log('device connected: ', this.device);
},
error => {
console.log('connect error: ', error);
}
);
}
And then, send the command with this code:
async sendCommandNew(id){
let noteOk;
let noteError;
let data;
data = this.stringToBytes(this.commandToSend);
let timerId = setInterval(() => {
BLE.write(id, "49535343-fe7d-4ae5-8fa9-9fafd205e455", "49535343-1e4d-4bd9-ba61-23c647249616", data).then((res) => {
console.log('res: ', res);
}).catch(() => {
console.log('res no');
}
)
}, 1000);
setTimeout(() => { clearInterval(timerId); console.log('stopped'); }, 5000);
}
This is the characteristic
Inside the plugin issue many people had this problem but no solution provided.

Cannot send image in base64 format with XHR to aws S3 in android(react-native)

I got very strange issue: we have scan functionality for documents in our app and as the result scan give's me encoded base64 image with photo. Everything is good on ios platform but when I trying to send my picture on android, I get xhr.status 0 and error. Also, next strange thing is that when I starting debug mode and enable network inspection in react-native-debugger, picture is sending without errors. I was trying it on release app version, installed on my device, but still got an error with status 0
XHR request
export const uploadXHRImage = (url: string, data: IDataUploadImage) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve('Image successfully uploaded to S3');
} else {
reject(localize('failedUploadImage'));
}
}
};
xhr.ontimeout = () => reject(localize('timeoutUploadImage'));
xhr.timeout = UPLOAD_IMAGE_TIMEOUT;
xhr.open('PUT', url);
xhr.setRequestHeader('Content-Type', data.type);
xhr.send(data);
});
};
Add to header:
"Content-Type": 'application/json',
"Connection": "close",
I found the answer: Android can not process xhr send image, while image isn't saved as file in cache or other directory. Also, android needs file:// before data. Example is here:
saveImage = (image: string) => {
if (IS_IOS) {
return `data:image/jpg;base64,${image}`;
}
const tempFileDirectory = `${fs.CachesDirectoryPath}`;
const tempFilePath = `${tempFileDirectory}/${uuidv4()}.jpg`;
fs.writeFile(tempFilePath, image, 'base64');
return `file://${tempFilePath}`;
};

Unhandled error Network error: Network request failed Error: Network request failed Error: at new ApolloError

I got this error in my application ( react-native ) when internet connection is lost.
When i start the app on offline mode, Initial component renders, try to execute the query, app crashes.
it works perfect when my app is connected with internet. But my application crashes when its not. How can i handle this error?
ExceptionsManager.js:71 "Unhandled error Network error: Network request failed Error: Network error: Network request failed at new ApolloError"
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { AsyncStorage } from 'react-native';
import {SubscriptionClient, addGraphQLSubscriptions} from 'subscriptions-transport-ws';
const wsClient = new SubscriptionClient('wss://172.20.32.6:5000', {
reconnect: true,
connectionParams: {
accessToken: 'jka sdhkjashd jkashdjk ashdas'
}
});
const networkInterface = createNetworkInterface({
uri: 'http://172.20.32.6:8000/graphql',
opts: {
credentials: 'same-origin'
}
});
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
networkInterface,
wsClient
);
const client = new ApolloClient({
dataIdFromObject: o => o.id,
networkInterface: networkInterfaceWithSubscriptions
});
networkInterface.use([{
applyMiddleware(req, next) {
if (!req.options.headers) {
req.options.headers = {}; // Create the header object if needed.
}
// get the authentication token from local storage if it exists
AsyncStorage.getItem('sessionToken').then((token) => {
req.options.headers.Authorization = token ? `${token}` : null;
next();
}
);
}
}]);
export default client;
To avoid this very unhelpful error, add something like this at the top of the component that renders your query result.
if (data && data.error) {
return (
<View>
<Text>{JSON.stringify(data.error)}</Text>
</View>
)
}
more info of dealing with error can be found in this github issue
https://github.com/apollographql/react-apollo/issues/604

Cloud Function Not Working

I want to add notifications to an online android chatting app I have made. I am new to cloud functions, so I tried using the code given here https://firebase.googleblog.com/2016/08/sending-notifications-between-android.html
My index.js file
var firebase = require('firebase-admin');
var request = require('request');
var API_KEY = "xyz"; // Your Firebase
Cloud Messaging Server API key
// Fetch the service account key JSON file contents
var serviceAccount = require("firebase.json");
// Initialize the app with a service account, granting admin privileges
firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
databaseURL: "https://firebaseio.com/"
});
ref = firebase.database().ref();
function listenForNotificationRequests() {
var requests = ref.child('notificationRequests');
requests.on('child_added', function(requestSnapshot) {
var request = requestSnapshot.val();
sendNotificationToUser(
request.username,
request.message,
function() {
console.log('notificationrecived, sent and removed- ' +
request.username + ' '+ request.message,);
requestSnapshot.ref.remove();
}
);
}, function(error) {
console.error(error);
});
};
function sendNotificationToUser(username, message, onSuccess) {
request({
url: 'https://fcm.googleapis.com/fcm/send',
method: 'POST',
headers: {
'Content-Type' :' application/json',
'Authorization': 'key='+API_KEY
},
body: JSON.stringify({
notification: {
title: message
},
to : '/topics/'+username
})
}, function(error, response, body) {
if (error) { console.error(error); }
else if (response.statusCode >= 400) {
console.error('HTTP Error: '+response.statusCode+' - '
+response.statusMessage);
}
else {n
onSuccess();
}
});
}
// start listening
listenForNotificationRequests();
I have successfully deployed this code to the server using node.js command line.
But this does not show up on the console and nor the logs that I added to debug
and the code doesn't seem to work. I have done everything given in the link i mentioned. I could use some help on how to fix my code
I don't know how big of a difference this makes, but in the Firebase admin set up page https://firebase.google.com/docs/admin/setup, it is mentioned that for Cloud Functions, the following line is sufficient for initialisation:-
var firebase = require('firebase-admin');
firebase.initializeApp(functions.config().firebase);
So, if you're going by the book, you may replace the initialisation line in your code with the one above and try running it again.
I didn't export my function listenForNotificationRequests() but called it only once at the end of the script.
Which is why it didn't show up on the Firebase Console.
I fixed this by simply exporting the function like this
exports.sendFollowerNotification = listenForNotificationRequests;

Angular2 custom request

I am using a custom HTTP request class for adding a Authorization Header to all of my requests, this works fine on almost every android device. Wired thing now is that I got some customer complaints that they are getting the 'No internet connection' error although they have a working network connection (other apps work and the errors are transmitted to the Sentry servers also).
As I am using Sentry error tracking I found out that these customers are all getting the error because the timeout error is thrown after 10 seconds for the first request at app start.
I guessed that something has to be wrong with this request so I built an alpha version for a limited number of users to track down the error (I send the options of every request to Sentry), but the requests look fine.
Next guess was that something is wrong with cordova-plugin-nativestorage on these devices but as I am catching them it should at lease return an empty token. No clue how to fix it right now. Any advice is appreciated!
export class CustomRequest {
apiToken: string = '';
constructor(private http: Http) { }
protected request(options: any): Observable<any> {
// If Native Storage doens't find a token, return an empty
let errorNativeStorage$ = function (): Observable<any> {
return Observable.of({ Token: '' });
};
// Get Token form Native Storage
let token$ = Observable.fromPromise(NativeStorage.getItem('JWT'))
.catch(errorNativeStorage$);
// Handle request errors
let genericError$ = function (error: Response | any): Observable<any> {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
Raven.captureException(error, { extra: { errorMsg: errMsg } });
return Observable.of({
Errors: { General: 'No internet connection.' }
});
};
// the request
let request$ = (options) => {
return this.http.request(new Request(options))
.retryWhen(error => error.delay(1000))
.timeout(10000, new Error('timeout'))
.map((res: Response) => res.json())
.catch(genericError$);
};
// get the token and build request
return token$
.map(jwt => {
if (options.body) {
if (typeof options.body !== 'string') {
options.body = JSON.stringify(options.body);
}
options.body = options.body.replace(/ /g, '').replace(/\r?\n|\r/g, '');
}
options.headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded, application/json'
});
if (jwt.Token) {
options.headers.append('Authorization', `Bearer ${jwt.Token}`);
}
Raven.captureMessage('request options', { level: 'info', environment: 'live', extra: options });
return options;
})
.switchMap(options => request$(options));
}
}
I am using:
Ionic 2.0.0-beta.11
Angular 2.0.0-rc.4
Most recent version of NativeStorage plugin from github
Devices with the error (only two examples, there are more):
Samsung SM-N910F (Webview: Chrome Mobile 53.0.2785, Android 6.0.1)
Samsung SM-G800F (Webview: Chrome Mobile 53.0.2785, Android 5.1.1)
If somebody's interested: The root cause was that people that upgraded Android somehow lost the chrome webview app and Angular was not working without one (of course). I solved it by packaging the crosswalk-webview in my app!

Categories

Resources