react-native-fetch-blob is blocking firebase calls

2020-07-22 09:53发布

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)
        })
};

2条回答
【Aperson】
2楼-- · 2020-07-22 10:34

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>

查看更多
看我几分像从前
3楼-- · 2020-07-22 10:38

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)
        })
};
查看更多
登录 后发表回答