Service Worker With Stream Connection Reset - service-worker

The code below is getting executed, but I keep getting
ERR_CONNECTION_RESET
addEventListener('fetch', function(event) {
const stream = new ReadableStream({
start(controller) {
controller.enqueue('test')
controller.close()
}});
event.waitUntil(event.respondWith(new Response(stream, {headers: {'Content-Type': 'text/html; charset=utf-8'}})))
});
If I replace the stream (in the response) with the same string inside the ReadableStream the response comes back correctly. I'm using the latest version of Chrome.
Is there something I'm missing?
This works below:
event.waitUntil(
event.respondWith(new Response('test', {headers: {'Content-Type': 'text/html;
charset=utf-8'}}))
)
The service worker is definitely loading correctly and responding to the fetch.

Solved! The text needs to be encoded first :)
controller.enqueue(new TextEncoder().encode('test'))

Related

Axios post request network error on android

So i'm posting a formdata object with axios to a node.js server. On iOS everything works perfectly, the data get posted and the image uploaded. But on android i'm getting this error
[AxiosError: Network Error]
here's my axios call
const handleSubmit = async (listing, { resetForm }) => {
const data = new FormData();
listing.images.forEach((image, index) =>
data.append("images", {
name: `product${Math.floor(Math.random() * 1000)}.`,
uri: image,
})
);
const res = await axios
.post("http://192.168.43.8:5000/products/addProduct", data, {
headers: {
"Content-Type": "multipart/form-data",
},
//tried adding this but didn't work out
transformRequest: (data) => data,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
// handle error
});
}
}
Please note that on iOS it works without a problem.
here's a screenshot of the error when i used the react native debugger
if you use android emulator you need to change your ip to 10.0.2.2
change this:
http://192.168.43.8:5000/products/addProduct
to this:
http://10.0.2.2:5000/products/addProduct
By default http calls are blocked from android 9 version onwards, you either need to make your api calls HTTPS or you need to explicitly allow connection to this IP in your manifest file. Please refer this SO thread. How to allow all Network connection types HTTP and HTTPS in Android (9) Pie?
For me i am getting axios error for my emulator and did not getting any error for ios simulator. The problem with my emulator is that it is not able to connect to Internet.
So I added google DNS server 8.8.8.8 (you can add any DNS server) for my mac and it worked.

iOS Workbox Background Sync - FetchEvent.respondWith received an error: UnknownError: Error preparing Blob/File data to be stored in object store

I have a PWA that runs offline with background sync running and it works on all browsers (Brave/Safari/Chrome/Firefox tested). I am able to add articles and upon adding an article it is stored in the indexedDB. If offline and the app can't reach the server to post the data the request goes into the workbox-background-sync as expected, and the article makes its way to my MySQL database once the network becomes active again.
However, on iOS Safari, the PWA works online but when I go offline and try post an article, the data makes its way into the indexedDB successfully but the background sync isn't added to the queue and i'm presented with the error
FetchEvent.respondWith received an error: UnknownError: Error preparing Blob/File data to be stored in object store
I'm assuming this is because the body of the request is a Blob. How would I go about storing the request and have iOS do the sync the next time the network is online?
Many thanks for any help provided.
Here are my snippets of the add article code (main.js), and my service worker code (sw.js)
function addAndPostArticle(e)
{
e.preventDefault();
const data = {
id: Date.now(),
title: document.getElementById('article-title').value,
content: document.getElementById('article-content').value
};
updateUI([data]);
saveArticleDataLocally([data]);
const headers = new Headers({'Content-Type': 'application/json'});
const body = JSON.stringify(data);
return fetch('/pwa/api/add.php', {
method: 'POST',
headers: headers,
body: body
});
}
sw.js
const bgSyncPlugin = new workbox.backgroundSync.Plugin('myQueueName', {
maxRetentionTime: 24 * 60 // Retry for max of 24 Hours
});
workbox.routing.registerRoute(
'/pwa/api/add.php',
workbox.strategies.networkOnly({
plugins: [bgSyncPlugin]
}),
'POST'
);

React Native Axios.get returned results not fresh

I'm using axios to fetch data for my React Native app and I'm having an issue only for iOS. I am able to fetch data from my server perfectly fine, however if I change any data from my API, the changes doesn't reflect in iOS at all, only when I re-install the app then the changes will take place. I'm still not able to pinpoint what is causing the issue. This is only happening in iOS, Android works perfectly fine.
Fetch Data code:
axios.get('http://www.example.com/api')
.then((response) => {
// console.log(response);
this.setState({ data: response.data, loading: false });
});
Please let me know if I miss out any information.
If this has already been asked, I would greatly appreciate if you are able to point me in the right direction.
Thank you so much!
my guess is that the page is read from the cache and so you get an old copy.
what you need to do is to add a date stamp to the link, in order to force the app to load a 'fresh' page.
it goes something like that:
axios.get('http://www.example.com/api?dt='+(new Date()).getTime())
.then((response) => {
// console.log(response);
this.setState({ data: response.data, loading: false });
});
It can be resolved by adding headers: {'Cache-Control': 'no-cache'} to the header.
axios.get('http://www.example.com/api',
headers: {'Cache-Control': 'no-cache'})
.then((response) => {
// console.log(response);
this.setState({ data: response.data, loading: false });
});

"message" : "Internal server error" issue with Lambda/API Gateway and iOS

I've set up a lambda function and created some GET and POST methods inside the API Gateway which seem to work fine when testing them inside the web application.
I am then trying to call the functions inside an iOS application which is set up using the mobile hub. The functions also work inside the testing facility via the mobile hub perfectly fine, however when I actually test the functions inside the app I get:
"message" : "Internal server error"
I know the error is not much to work from, but I can't figure out a way to get a more detailed error description.
Any ideas?
This may happen because your Lambda function is not set to return a HTTP status code.
Changing from
exports.handler = (event, context, callback) => {
callback(null, 'Hello from Lambda');
};
to
exports.handler = (event, context, callback) => {
callback(null, { statusCode: 200, body: 'Hello from Lambda' });
};
Should fix the issue.
The JSON.stringify() solved my issue. The response.body needs to be in String format and not as JSON. I hope this helps.
exports.sendRes = (body, status = 200) => {
var response = {
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(body)
};
return response;
};
I had the same issue with the following code:
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: event
};
};
To fix all I had to do was JSON.stringify() the body.
exports.handler = async event => {
console.log("hello world");
return {
statusCode: 200,
body: JSON.stringify(event), // <-- here
};
};
I had this problem until I click in "Deploy API" under the "Actions" button.
The other possible reason could be the payload/request/response limits on API Gateway (10MB) and/or Lambda (6MB)
None of the above answers worked for me. I was having a permission issue. Below is how I solved it.
Context
This is my lambda function:
exports.handler = function(event, context, callback) {
callback(null, {
statusCode: '200',
body: JSON.stringify({ 'message': 'hello world' }),
headers: {
'Content-Type': 'application/json',
},
});
};
I used terraform to provision api gateway and lambda. I used the example code provided by this blog post.
Diagnosis
In the lambda console I ran a test event on my lambda. As my lambda was super basic I used the hello world test template, named, and saved it. The test return success.
I checked cloudwatch logs, but couldn't find anything of use. I'm new to AWS so wasn't sure if I had to set anything up.
In the api gateway console I ran a test event. I just added Content-Type:application/json to the headers of the event and ran the test. For whatever weird reason the test results returned on the right side of the browser so had to scroll to the right to see them.
I got this result: Execution failed due to configuration error: Invalid permissions on Lambda function
SOLUTION
I checked the basic terraform example for api gateway and lambda integration here and noticed I was missing the aws_lambda_permission resource. This is needed to give permission to api gateway to invoke the lambda function.
For those that aren't using terraform here is a link to the aws docs on how to create the appropriate permissions.
please try to
Give execute lambda permission API Gateway
tick checkbox : Use Lambda Proxy integration
Handle null pointer for query string, headers & body.
I solved the issue by adding "isBase64Encoded": False/True to my lambda response
results = {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps(res),
"isBase64Encoded": False
}
In my case, the issue resolved while adding the integration Response and redeploying API

React native socket io no events being emitted from client

Trying to use socket.io-client with react-native (ios for now), so far connection / receiving server side events from client seems to be working fine. However I can't seem to emit any events from the client?
Client
var socket = io("http://localhost:3000");
socket.on('connect', function(){
socket.on('ping', function(e) {
console.log('Server emitted ping: ' + e);
socket.emit('pong', 'hi server!');
});
socket.on('disconnect', function(){
console.log("disconnect");
});
});
Server(Node.js)
var io = require('socket.io')(server);
io.on('connection', function (socket) {
console.log('connected...');
socket.on('pong', function (data) {
console.log("Hmm?");
console.log(data);
});
setTimeout(function() {
console.log("Saying hello");
socket.emit('ping', { message: 'Hello from server ' + Date.now() });
}, 1000);
});
So from the server side, I see the logs
connected...
Saying hello
And in the client I see "Server emitted ping...", but the pong event doesn't seem to be doing anything? I tried catching all events on the server through solutions mentioned in StackOverflow, but it looked like no event was coming from the client. Any ideas?
Using latest RN version 0.31.
Also seeing this error when I first run the app in Xcode, could it be the reason?:
[warn][tid:main][RCTEventEmitter.m:52] Sending `websocketFailed` with no listeners registered.
please try:
io.sockets.on('connection', function(socket) {
....
})

Resources