我的组件状态中有两个图像路径
我尝试在函数内部上传其中一个图像,但出现错误:
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。谢谢!
答案 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外,此方法不使用任何第三方库。
获取要上传的图像的文件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
}
})
从图像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);
});
}
我们有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的更多信息。