在React Native中将图像上传到Firebase

时间:2017-02-14 01:36:00

标签: firebase react-native firebase-storage

我的组件状态中有两个图像路径

enter image description here

我尝试在函数内部上传其中一个图像,但出现错误:

Firebase Storage: Invalid argument in 'put' at index 0: Expected Blob or file

和我的功能

submitImages = () => {

    // Upload images to Firebase storage
    let user = firebaseAuth.currentUser;
    let imagesRef = storageRef.child('productImages/' + user.uid);
    imagesRef.put(this.state.imageFront).then(snapshot => {
        console.log('Uploaded ' + this.state.imageFront);
    });
}

我应该做些什么来将这些图像传输到Firebase。谢谢!

6 个答案:

答案 0 :(得分:10)

错误说明你需要使用blob。您可以使用react-native-fetch-blob:https://github.com/wkh237/react-native-fetch-blob

查看此示例:https://github.com/dailydrip/react-native-firebase-storage/blob/master/src/App.js#L43-L69

答案 1 :(得分:7)

我发布了我的代码,因为这对我来说有点令人沮丧:

要将图像上传到firebase.storage,您需要将图像上传为Blob。如果您不知道Blob是什么,请不要担心: BLOB 代表 B inary L arge OB JECT。

第1步。

npm install --save react-native-fetch-blob

第2步。

// copy and paste this code where you will handle the file upload

import RNFetchBlob from 'react-native-fetch-blob'

const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
window.Blob = Blob;

第3步。

// The uploadImage function that you are going to use:

function uploadImage(uri, mime = 'image/jpeg', name) {

  return new Promise((resolve, reject) => {
    let imgUri = uri; let uploadBlob = null;
    const uploadUri = Platform.OS === 'ios' ? imgUri.replace('file://', '') : imgUri;
    const { currentUser } = firebase.auth();
    const imageRef = firebase.storage().ref(`/jobs/${currentUser.uid}`)

    fs.readFile(uploadUri, 'base64')
      .then(data => {
        return Blob.build(data, { type: `${mime};BASE64` });
      })
      .then(blob => {
        uploadBlob = blob;
        return imageRef.put(blob, { contentType: mime, name: name });
      })
      .then(() => {
        uploadBlob.close()
        return imageRef.getDownloadURL();
      })
      .then(url => {
        resolve(url);
      })
      .catch(error => {
        reject(error)
    })
  })
}

那你怎么称呼这个功能? 传递图像的URI作为第一个参数。在我的情况img1, img2, img3中,其中指向图像URI的变量,我想上传的变量在我的手机上。他们看起来像'/Phone/Pics/imageToUpload.jpeg'等等。

作为第二个参数,您可以传递'image/jpeg',最后一个参数是您要为图像提供的名称。选择你喜欢的名字。

但沃尔特我有几张图片,想要上传它们并希望正确处理上传。如果一个上传成功而另一个没有成功怎么办?

然后执行此操作:

let imgPromises = [];
imgPromises.push(uploadImage(img1, 'image/jpeg', 'imageOne'));
imgPromises.push(uploadImage(img2, 'image/jpeg', 'imageTwo'));
imgPromises.push(uploadImage(img3, 'image/jpeg', 'imageOne'));

Promise.all(imgPromises).then(urls => {
  // ALL IMAGES SUCCEEDED and you will get an array of URIS that you can save to your database for later use!
}).catch(error => {
  // One OR many images failed the upload. Give feedback to someone.
})

答案 2 :(得分:4)

您可以使用react-native-firebase将图片上传到storge https://rnfirebase.io/

const storage = firebase.storage();
const sessionId = new Date().getTime();
const imageRef = storage.ref('images').child(`${sessionId}`);
return imageRef.putFile(uri);

答案 3 :(得分:0)

如果你不介意使用cloudinary,我会展示如何上传,然后将上传的url保存到firebase https://medium.com/@ifeoluwaking24/how-to-upload-an-image-in-expo-react-native-to-firebase-using-cloudinary-24aac981c87

您也可以尝试点心,但请确保添加cloud_name和upload_preset https://snack.expo.io/@ifeking/upload-to-cloudinary

答案 4 :(得分:0)

一段时间以来,我将Firebase JS SDK与React Native一起使用。使用此线程中提到的该库,您需要使用rn-fetch-blob之类的库(不再维护react-native-fetch-blob),以便为Firebase Storage put()方法提供blob。

最近我开始使用React Native Firebase。正如他们在其网站上所说的:“将本机Firebase SDK与React Native Firebase结合使用,可以使用Firebase JS SDK上不存在的设备SDK”。

使用React-Native-Firebase,您不需要任何额外的库即可将图像上传到Firebase Storage,并且代码变得更加简洁:

export const uploadImage = (path, mime = 'application/octet-stream') => {
  return new Promise((resolve, reject) => {
    const imageRef = firebase.storage().ref('images').child('filename.jpg');

    return imageRef.put(path, { contentType: mime })
      .then(() => {
        return imageRef.getDownloadURL();
      })
      .then(url => {
        resolve(url);
      })
      .catch(error => {
        reject(error);
        console.log('Error uploading image: ', error);
      });
  });
};

答案 5 :(得分:0)

到目前为止,这是我发现的使用React Native将文件/图像上传到Firebase存储的最佳方法。除Expo SDK外,此方法不使用任何第三方库。

  1. 获取要上传的图像的文件URI 。为此,我们将需要使用Expo ImagePicker。包含此代码块的最佳位置是使用onPress处理程序的按钮。

    ImagePicker.launchImageLibraryAsync({ 
      mediaTypes: "Images"
    }).then((result)=>{ 
    
      if (!result.cancelled) {
        // User picked an image
        const {height, width, type, uri} = result;
        return uriToBlob(uri); // will follow later
      }
    
    })
    
  2. 从图像URI生成BLOB 。有很多第三方库可以帮助您做到这一点。但是,如果您不想安装库,则可以使用XMLHttpRequest。 React Native文档recommends we use the Fetch API,但是现在我们不能使用它,因为它将抛出一个错误,我们只能获取https://网址,但是我们的URI是file://。有一种方法可以解决这个问题,但是使用XMLHttpRequest将使事情变得简单得多。

    uriToBlob = (uri) => {
    
    return new Promise((resolve, reject) => {
    
      const xhr = new XMLHttpRequest();
    
      xhr.onload = function() {
        // return the blob
        resolve(xhr.response);
      };
    
      xhr.onerror = function() {
        // something went wrong
        reject(new Error('uriToBlob failed'));
      };
    
      // this helps us get a blob
      xhr.responseType = 'blob';
    
      xhr.open('GET', uri, true);
      xhr.send(null);
    
    });
    
    }
    
  3. 我们有BLOB,让我们将其上传到Firebase。这部分非常简单,如Firebase Docs中所述。

    uploadToFirebase = (blob) => {
    
    return new Promise((resolve, reject)=>{
    
      var storageRef = firebase.storage().ref();
    
      storageRef.child('uploads/photo.jpg').put(blob, {
        contentType: 'image/jpeg'
      }).then((snapshot)=>{
    
        blob.close(); // let's free up the blob
    
        resolve(snapshot);
    
      }).catch((error)=>{
    
        reject(error);
    
      });
    
    });
    
    
    }
    

就是这样,您现在可以将文件上传到Firebase Storage。关键的部分是获取文件URI并将其转换为BLOB。您可以了解有关此方法here的更多信息。