我正在尝试为Firebase Cloud Storage进行上传功能。我正在使用RNFetchBlob以及react-native-image-picker。我可以选择照片,但不会上传。所有其他Firebase功能都很好用,并且可以通过React-Native-Firebase安装...
'fs.readFile'之后似乎什么也没发生。
import React, { Component } from 'react'
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Platform,
Image,
ActivityIndicator
} from 'react-native'
import ImagePicker from 'react-native-image-picker'
import RNFetchBlob from 'rn-fetch-blob'
import firebase from 'react-native-firebase';
const storage = firebase.storage()
// Prepare Blob support
const Blob = RNFetchBlob.polyfill.Blob
const fs = RNFetchBlob.fs
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest
window.Blob = Blob
const uploadImage = (uri, mime = 'application/octet-stream') => {
return new Promise((resolve, reject) => {
const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri
const sessionId = new Date().getTime()
let uploadBlob = null
const imageRef = storage.ref('images').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()
return imageRef.getDownloadURL()
})
.then((url) => {
resolve(url)
})
.catch((error) => {
reject(error)
})
})
}
class Demo extends Component {
constructor(props) {
super(props)
this.state = {}
}
_pickImage() {
this.setState({ uploadURL: '' })
ImagePicker.launchImageLibrary({}, response => {
uploadImage(response.uri)
.then(url => this.setState({ uploadURL: url }))
.catch(error => console.log(error))
})
}
render() {
return (
<View style={ styles.container }>
{
(() => {
switch (this.state.uploadURL) {
case null:
return null
case '':
return <ActivityIndicator />
default:
return (
<View>
<Image
source={{ uri: this.state.uploadURL }}
style={ styles.image }
/>
<Text>{ this.state.uploadURL } {this.state.uploadURL}</Text>
</View>
)
}
})()
}
<TouchableOpacity onPress={ () => this._pickImage() }>
<Text style={ styles.upload }>
Upload
</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
image: {
height: 200,
resizeMode: 'contain',
},
upload: {
textAlign: 'center',
color: '#333333',
padding: 10,
marginBottom: 5,
borderWidth: 1,
borderColor: 'gray'
},
})
export default Demo
选择照片时,我在控制台中收到此错误:
filePath.replace不是函数。 (在'filePath.replace('file://', ”)','filePath.replace'未定义)]
答案 0 :(得分:1)
只需将图像URL直接传递到存储引用。您不再需要创建Blob文件。我猜Firebase现在在内部处理它。
这是我刚刚与react-native-image-crop-picker一起测试的一个示例:
import firebase from 'react-native-firebase';
import ImagePicker from 'react-native-image-crop-picker';
export default class ImageUploadService {
static init() {}
static openPickerAndUploadImage() {
const uid = '12345';
ImagePicker.openPicker({
width: 300,
height: 300,
cropping: true,
mediaType: 'photo',
})
.then(image => {
const imagePath = image.path;
const imageRef = firebase
.storage()
.ref(uid)
.child('dp.jpg');
let mime = 'image/jpg';
imageRef
.put(imagePath, { contentType: mime })
.then(() => {
return imageRef.getDownloadURL();
})
.then(url => {
// You could now update your users avatar for example
//firebase.database().ref('users').child(uid).update({ ...userData})
console.log('URL', url);
});
})
.catch(error => {
console.log(error);
});
}
}
ImageUploadService.init();
现在只需在您的组件之一中调用ImageUploadService.openopenPickerAndUploadImage()。
我确信这也可以与react-native-image-picker一起使用,只需删除代码中的blob部分,然后将图像网址直接传递到imageRef.put
==>
const uploadImage = (uri, mime = 'application/octet-stream') => {
return new Promise((resolve, reject) => {
const imagePath = uri;
const imageRef = firebase
.storage()
.ref('images')
.child('dp.jpg');
let mime = 'image/jpg';
imageRef
.put(imagePath, { contentType: mime })
.then(() => {
return imageRef.getDownloadURL();
})
.then(resolve)
.catch(reject);
});
};