firebase-storage-upload-example
firebase-storage-upload-example copied to clipboard
Uploading results as empty file without mime type without errors
Have anyone same problem?
Same problem here. Looking for a workaround, will update if I find something.
Problem is going from fetch polyfill package and there are PR that not merged yet Thanks for that author, I made quick fix that resolves problem
;(function(self) {
'use strict'
function parseHeaders(rawHeaders) {
var headers = new Headers()
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ')
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
var parts = line.split(':')
var key = parts.shift().trim()
if (key) {
var value = parts.join(':').trim()
headers.append(key, value)
}
})
return headers
}
var supportsBlob =
'FileReader' in self &&
'Blob' in self &&
(function() {
try {
new Blob()
return true
} catch (e) {
return false
}
})()
self.fetch = function(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init)
var xhr = new XMLHttpRequest()
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
}
options.url =
'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
var body = 'response' in xhr ? xhr.response : xhr.responseText
resolve(new Response(body, options))
}
xhr.onerror = function() {
reject(new TypeError('Network request failed'))
}
xhr.ontimeout = function() {
reject(new TypeError('Network request failed'))
}
xhr.open(request.method, request.url, true)
if (request.credentials === 'include') {
xhr.withCredentials = true
} else if (request.credentials === 'omit') {
xhr.withCredentials = false
}
if ('responseType' in xhr && supportsBlob) {
xhr.responseType = 'blob'
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value)
})
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
})
}
self.fetch.polyfill = true
})(typeof self !== 'undefined' ? self : this)
facebook/react-native#22063
Thank you so much for that!
I'm having this issue as well when using the ios simulator. I checked in node_modules/whatwg-fetch and it has that change that the PR added. Help!
I think the problem is that whatwg-fetch
is not setting the type when building the blob.
this worked for me.
function urlToBlob(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.onerror = reject;
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
resolve(xhr.response);
}
};
xhr.open('GET', url);
xhr.responseType = 'blob'; // convert type
xhr.send();
})
}
@yonahforst thanks!!
You the man @yonahforst
AWESOME @yonahforst !!!!!! Just completely saved me, thank you! 🎖
Hey guys ... this is a huge issue for me. I am now having an issue with @yonahforst 's function... for some reason the func switching views in my app after PUT. When I use the old fetch the problem doesn't happen (alas no blob either)... is anyone else getting this with the function above?
Would rolling back SDKs fix this entire issue??
Problem is going from fetch polyfill package and there are PR that not merged yet Thanks for that author, I made quick fix that resolves problem
;(function(self) { 'use strict' function parseHeaders(rawHeaders) { var headers = new Headers() var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ') preProcessedHeaders.split(/\r?\n/).forEach(function(line) { var parts = line.split(':') var key = parts.shift().trim() if (key) { var value = parts.join(':').trim() headers.append(key, value) } }) return headers } var supportsBlob = 'FileReader' in self && 'Blob' in self && (function() { try { new Blob() return true } catch (e) { return false } })() self.fetch = function(input, init) { return new Promise(function(resolve, reject) { var request = new Request(input, init) var xhr = new XMLHttpRequest() xhr.onload = function() { var options = { status: xhr.status, statusText: xhr.statusText, headers: parseHeaders(xhr.getAllResponseHeaders() || '') } options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL') var body = 'response' in xhr ? xhr.response : xhr.responseText resolve(new Response(body, options)) } xhr.onerror = function() { reject(new TypeError('Network request failed')) } xhr.ontimeout = function() { reject(new TypeError('Network request failed')) } xhr.open(request.method, request.url, true) if (request.credentials === 'include') { xhr.withCredentials = true } else if (request.credentials === 'omit') { xhr.withCredentials = false } if ('responseType' in xhr && supportsBlob) { xhr.responseType = 'blob' } request.headers.forEach(function(value, name) { xhr.setRequestHeader(name, value) }) xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit) }) } self.fetch.polyfill = true })(typeof self !== 'undefined' ? self : this)
@evilandfox can you explain a bit more how this fix works?
@barrylachapelle That's very simple. It is just the original code for overwriting global fetch function with additional
if ('responseType' in xhr && supportsBlob) {
xhr.responseType = 'blob'
}
line of fix. And fetch
function uses parseHeaders
and supportsBlob
out of its body, so we also have to add them.
@jlsilva10 I used the solution above directly in my code. Use urlToBlob
, pass in the uri
for your file/document/image, and that will return you a promise which returns a blob for your file/document/image. Then, you can use that blob directly in a file upload using fetch, example:
/**
* Get file blob using local file URI
*/
const blob = await uriToBlob(uri);
const options = {
method: "PUT",
body: blob,
headers: {
"Content-Type": "image/jpeg",
},
};
/**
* Upload blob to your API endpoint
*/
return fetch("your-api/some-endpoint", options);
Thanks! Worked like a charm ;)
Use that urlToBlob, and return this:
Promise { "_40": 0, "_55": null, "_65": 0, "_72": null, }
That returns a promise, you need to await for it.
I think the problem is that
whatwg-fetch
is not setting the type when building the blob.this worked for me.
function urlToBlob(url) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(); xhr.onerror = reject; xhr.onreadystatechange = () => { if (xhr.readyState === 4) { resolve(xhr.response); } }; xhr.open('GET', url); xhr.responseType = 'blob'; // convert type xhr.send(); }) }
This has to be in the sample code. It took 2 days to figure out the issue.
@barrylachapelle That's very simple. It is just the original code for overwriting global fetch function with additional
if ('responseType' in xhr && supportsBlob) { xhr.responseType = 'blob' }
line of fix. And
fetch
function usesparseHeaders
andsupportsBlob
out of its body, so we also have to add them.
Can you tell what file should we edit, please?
@barrylachapelle That's very simple. It is just the original code for overwriting global fetch function with additional
if ('responseType' in xhr && supportsBlob) { xhr.responseType = 'blob' }
line of fix. And
fetch
function usesparseHeaders
andsupportsBlob
out of its body, so we also have to add them.Can you tell what file should we edit, please?
I guess this one /home/you/yourprojectfolder/node_modules/react-native/Libraries/vendor/core/whatwg-fetch.js
I cannot patch the whatwg-fetch.js correctly I am getting this.initBody is not a function
error please someone share the full code.
@EnginYilmaz just use yonahforst code above
@EnginYilmaz just use yonahforst code above
In my situation I am not using GET or PUT just URL for the fetch function for example
onMessagePress() {
...
this.setState({ error: '', loading: true, loadingSendingMessage: true });
myURL = 'https://www.somedomain.com:443/send_message.php' + '?message=' + this.state.bodymessage + '&senderid=' + this.state.email + '&receipentid=' + this.props.navigation.getParam('email');
return fetch(myURL)
.then((response) => response.json())
.then((responseJson) => {
if (this._mounted) {
this.setState({ error: responseJson.success });
}
if (responseJson.success == true) {
if (this._mounted) {
this.setState({ error: "Successfully sent message", loadingSendingMessage: false })
}
} else {
if (this._mounted) {
this.setState({ error: responseJson.success })
}
}
})
}
@EnginYilmaz same thing, just use the code from yonahforst and do urlToBlob(myURL)
instead of fetch(myURL)
@EnginYilmaz same thing, just use the code from yonahforst and do
urlToBlob(myURL)
instead offetch(myURL)
@jrnk I tried but function never finishes loading and getting warning message
Possible Unhandled Promise Rejection (id: 0): TypeError:response.json is not a function(In 'response.json()', response.json is undefined
@EnginYilmaz how are you using it ? please post your code
this should work =
function urlToBlob(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.onerror = reject;
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
resolve(xhr.response);
}
};
xhr.open('GET', url);
xhr.responseType = 'blob'; // convert type
xhr.send();
})
}
//inside async function
try {
const response = await urlToBlob(imageUrl)
await fetch(url, { method: 'PUT', body: response })
} catch (e) {
console.log('error is:', e);
}
I am getting Network request failed 504:29 error message but not using local or remote image so no image URL. I am using it as https://github.com/expo/firebase-storage-upload-example/issues/13#issuecomment-458614689
I think it is better not to use fetch anywhere I will have to change all the code to XMLHttpRequest on each scene. I have fetch function nearly on 20 pages in total! I hope this will help anyone consider to use fetch in their project.
@EnginYilmaz surely you can just write a fetch function and call it in your 20 pages, it will be a simple find and search ?
@farzd I have lots of codes like
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
What will happen to after .then I need to write them from scratch.
Besides, I afroid getting same error message after getting away from fetch