问题
I have a react native app that uses Firebase, firestore. for uploading images i am using "react-native-fetch-blob" to create a Blob.
in the js file that I use to upload the file, my code look like this:
const Blob = RNFetchBlob.polyfill.Blob
const fs = RNFetchBlob.fs
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
window.Blob = Blob
**
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
**
because of this window.XMLHttpRequest my app is blocked and not getting any response from firebase(not catch / nothing => just passing thrue the code).
if i removed this line i can read/write to the firestore, bat I can't upload an image.
is there anything i can do for uploading images and keep writing to firestore?
Heare is my page:
import ImagePicker from 'react-native-image-crop-picker';
import RNFetchBlob from 'react-native-fetch-blob'
import firebase from 'firebase';
const Blob = RNFetchBlob.polyfill.Blob
const fs = RNFetchBlob.fs
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
window.Blob = Blob
export const choozFile = (isSmalImg) => {
let options = {
width: isSmalImg ? 100 : 690,
height: isSmalImg ? 100 : 390,
cropping: true,
mediaType: 'photo'
};
return new Promise((resolve, reject) => {
ImagePicker.openPicker(options).then(response => {
let source = { uri: response.path };
resolve({ avatarSource: source, isProfileImg: isSmalImg })
})
});
}
export const addReportToFirebase = (obj = {}, uri, isProfile, mime = 'application/octet-stream') => {
obj["uId"] = "JtXNfy34BNRfCoRO6luwhIJke0l2";
const storage = firebase.storage();
const db = firebase.firestore();
const uploadUri = uri;
const sessionId = new Date().getTime();
let uploadBlob = null;
const imageRef = storage.ref(`images${isProfile ? '/profile' : ''}`).child(`${sessionId}`)
fs.readFile(uploadUri, 'base64')
.then((data) => {
return Blob.build(data, { type: `${mime};BASE64` })
})
.then((blob) => {
uploadBlob = blob
return imageRef.put(blob, { contentType: mime })
})
.then(() => {
uploadBlob.close()
imageRef.getDownloadURL().then((url)=>{
obj['image'] = url;
db.collection("reports").add(obj).then(() => {
console.log("Document successfully written!");
}).catch((err) => {
console.error("Error writing document: ", err);
});
})
})
.catch((error) => {
console.log('upload Image error: ', error)
})
};
回答1:
I had same issue , i did some trick to resolve this. This might not be most correct solution but it worked for me.
Trick is keep RNFetchBlob.polyfill.XMLHttpRequest
in window.XMLHttpRequest
only for the upload operation. Once you done with uploading image to storage revert window.XMLHttpRequest
to original value.
your code will look like this.
import ImagePicker from 'react-native-image-crop-picker';
import RNFetchBlob from 'react-native-fetch-blob'
import firebase from 'firebase';
const Blob = RNFetchBlob.polyfill.Blob
const fs = RNFetchBlob.fs
window.Blob = Blob
export const choozFile = (isSmalImg) => {
let options = {
width: isSmalImg ? 100 : 690,
height: isSmalImg ? 100 : 390,
cropping: true,
mediaType: 'photo'
};
return new Promise((resolve, reject) => {
ImagePicker.openPicker(options).then(response => {
let source = { uri: response.path };
resolve({ avatarSource: source, isProfileImg: isSmalImg })
})
});
}
export const addReportToFirebase = (obj = {}, uri, isProfile, mime = 'application/octet-stream') => {
obj["uId"] = "JtXNfy34BNRfCoRO6luwhIJke0l2";
const storage = firebase.storage();
const db = firebase.firestore();
const uploadUri = uri;
const sessionId = new Date().getTime();
let uploadBlob = null;
//keep reference to original value
const originalXMLHttpRequest = window.XMLHttpRequest;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
const imageRef = storage.ref(`images${isProfile ? '/profile' : ''}`).child(`${sessionId}`)
fs.readFile(uploadUri, 'base64')
.then((data) => {
return Blob.build(data, { type: `${mime};BASE64` })
})
.then((blob) => {
uploadBlob = blob
return imageRef.put(blob, { contentType: mime })
})
.then(() => {
uploadBlob.close();
//revert value to original
window.XMLHttpRequest = originalXMLHttpRequest ;
imageRef.getDownloadURL().then((url)=>{
obj['image'] = url;
db.collection("reports").add(obj).then(() => {
console.log("Document successfully written!");
}).catch((err) => {
console.error("Error writing document: ", err);
});
})
})
.catch((error) => {
console.log('upload Image error: ', error)
})
};
回答2:
that simple,,u can try this to upload image
<i>
getSelectedImages = (selectedImages, currentImage)=>{
const image = this.state.uri
let uploadBlob = null
let mime = 'image/jpg'
const originalXMLHttpRequest = window.XMLHttpRequest;
const originalBlob = window.Blob;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
window.Blob = RNFetchBlob.polyfill.Blob
const imageRef = firebase.storage().ref('posts').child(this.state.uri)
RNFetchBlob.fs.readFile(image, 'base64')
.then((data) => {
return Blob.build(data, { type: `${mime};BASE64` })
})
.then((blob) => {
uploadBlob = blob
return imageRef.put(blob, { contentType: mime })
})
.then(() => {
uploadBlob.close()
window.XMLHttpRequest = originalXMLHttpRequest ;
window.Blob = originalBlob
return imageRef.getDownloadURL()
})
.then((url) => {
firebase.database().ref('groub').child(params.chat).child('message').push({
createdAt:firebase.database.ServerValue.TIMESTAMP,
image:url,
user:{
_id:params.id,
name:params.name,
},
})
alert('Upload Sukses')
})
.catch((error) => {
console.log(error);
})
}
</i>
来源:https://stackoverflow.com/questions/48215067/react-native-fetch-blob-is-blocking-firebase-calls-n-react-native-app