在 React Native 中上传图片到 Firebase
Uploading Image to Firebase in React Native
我的组件状态中有两个图像路径
我尝试在函数内上传其中一张图片,但出现错误:
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。谢谢!
错误提示您需要使用 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
我正在发布我的代码,因为这对我来说有点令人沮丧:
要将图像上传到 firebase.storage,您需要将图像作为 Blob 上传。如果你不知道 Blob 是什么,别担心:BLOB 代表 Binary Large OBject.
步骤 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,我想上传这些 URI 在我的 phone 上。它们看起来像 '/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.
})
如果你不介意使用 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
可以使用react-native-firebase上传图片存储https://rnfirebase.io/
const storage = firebase.storage();
const sessionId = new Date().getTime();
const imageRef = storage.ref('images').child(`${sessionId}`);
return imageRef.putFile(uri);
有一段时间我使用 Firebase JS SDK with React Native. Using this library, as referred in this thread you need to use a library like rn-fetch-blob(react-native-fetch-blob 不再维护)来为 Firebase Storage put() 方法提供 blob。
最近我开始使用 React Native Firebase。正如他们在他们的网站上所说 "Using the native Firebase SDKs with React Native Firebase allows you to consume device SDKs which don't exist on the Firebase JS SDK".
使用 React-Native-Firebase,您不需要任何额外的库即可将图像上传到 Firebase 存储,并且您的代码变得更加简洁:
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);
});
});
};
到目前为止,这是我发现使用 React Native 将 file/image 上传到 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. The React Native docs recommends we use the Fetch API,但是现在我们不能使用它,因为它会抛出一个错误,我们只能获取https://
urls,但是我们的 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 存储。关键部分是获取文件 URI 并将其转换为 BLOB。您可以阅读有关此方法的更多信息 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。谢谢!
错误提示您需要使用 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
我正在发布我的代码,因为这对我来说有点令人沮丧:
要将图像上传到 firebase.storage,您需要将图像作为 Blob 上传。如果你不知道 Blob 是什么,别担心:BLOB 代表 Binary Large OBject.
步骤 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,我想上传这些 URI 在我的 phone 上。它们看起来像 '/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.
})
如果你不介意使用 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
可以使用react-native-firebase上传图片存储https://rnfirebase.io/
const storage = firebase.storage();
const sessionId = new Date().getTime();
const imageRef = storage.ref('images').child(`${sessionId}`);
return imageRef.putFile(uri);
有一段时间我使用 Firebase JS SDK with React Native. Using this library, as referred in this thread you need to use a library like rn-fetch-blob(react-native-fetch-blob 不再维护)来为 Firebase Storage put() 方法提供 blob。
最近我开始使用 React Native Firebase。正如他们在他们的网站上所说 "Using the native Firebase SDKs with React Native Firebase allows you to consume device SDKs which don't exist on the Firebase JS SDK".
使用 React-Native-Firebase,您不需要任何额外的库即可将图像上传到 Firebase 存储,并且您的代码变得更加简洁:
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);
});
});
};
到目前为止,这是我发现使用 React Native 将 file/image 上传到 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. The React Native docs recommends we use the Fetch API,但是现在我们不能使用它,因为它会抛出一个错误,我们只能获取
https://
urls,但是我们的 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 存储。关键部分是获取文件 URI 并将其转换为 BLOB。您可以阅读有关此方法的更多信息 here.