React + Firebase 存储 + 文件上传和进度显示
Posted
技术标签:
【中文标题】React + Firebase 存储 + 文件上传和进度显示【英文标题】:React + Firebase Storage + File upload and progress display 【发布时间】:2018-01-19 10:47:24 【问题描述】:我一直在关注这个上传恶作剧的 Firebase 存储图像。我被困住了。我该如何显示上传进度?我刚刚意识到使用状态可能不是要走的路,因为我会一遍又一遍地调用 setState。你有想法吗?
我想我需要某种递归函数,但我在哪里调用它?我不能在 Promise 中调用它可以吗?
// You'll need to set the rules to allow un-authed uploading however.
// Here's how to allow public: goto your firebase console and select the storage tab then the rules tab and change to:
//
// service firebase.storage
// match /b/bucket/o
// match /allPaths=**
// allow read, write;
//
//
//
//
//
// I just threw together an infinite grow animation here for shits, however, I use styled components in my own app so I will access the this.state.percent value in the "actual" animation.
const config =
apiKey: "KEY",
authDomain: "DOMAIN",
databaseURL: "DB_URL",
projectId: "ID",
storageBucket: "BUCKET",
messagingSenderId: "MSG_ID"
;
firebase.initializeApp(config);
const storageRef = firebase.storage().ref()
class App extends React.Component
constructor()
super()
this.state =
uploading: false,
percent: 0,
file: '',
error: ''
this.handleFileSelect = this.handleFileSelect.bind(this)
this.handleFileUpload = this.handleFileUpload.bind(this)
handleFileSelect(e)
this.setState(file: e.target.files[0])
handleFileUpload()
this.setState(uploading: true)
storageRef.child('images')
.put(this.state.file)
.then(snap =>
this.setState(uploading: false)
// the loading percent logic here?
// how do i keep tabs on the percent?
)
.catch(err => this.setState(error: err.message))
render()
return (
<div className='container'>
<div className='form'>
<input type='file' onChange=this.handleFileSelect/>
<button onClick=this.handleFileUpload>Upload</button>
</div>
this.state.uploading
? <div>
<div className='load-bar'/>
<span>Uploading: this.state.percent%</span>
</div>
: ''
<pre>
<code>
this.state.error ? <span className='error'>this.state.error</span> : ''
JSON.stringify(this.state.file, null, 2)
</code>
</pre>
</div>
)
ReactDOM.render(<App/>, document.getElementById('root'))
body
background: #212121;
color: #dbdbdb;
.form
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 1rem;
margin: 1rem;
background: rgba(0,0,0,0.4);
.error
font-size: 14px;
text-align: center;
color: red;
.load-bar
height: 20px;
width: 0px;
background: lime;
animation: grow 5s linear forwards;
@keyframes grow
from
width: 0px;
to
width: 100%;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.2.0/firebase.js"></script>
<div id='root'></div>
【问题讨论】:
【参考方案1】:终于在 firebase 文档(所有地方)中找到了答案。去图吧。
这是瘦米妮:
var uploadTask = storageRef.child('images/rivers.jpg').put(file);
// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on('state_changed', function(snapshot)
// Observe state change events such as progress, pause, and resume
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
switch (snapshot.state)
case firebase.storage.TaskState.PAUSED: // or 'paused'
console.log('Upload is paused');
break;
case firebase.storage.TaskState.RUNNING: // or 'running'
console.log('Upload is running');
break;
, function(error)
// Handle unsuccessful uploads
, function()
// Handle successful uploads on complete
// For instance, get the download URL: https://firebasestorage.googleapis.com/...
var downloadURL = uploadTask.snapshot.downloadURL;
);
干杯。
【讨论】:
如果您不使用状态,您将如何更新 如果您愿意,可以保存进度以说明...如果我没记错的话,我在这个项目上使用的是 mobx(已经有一段时间了) 这给我带来了巨大的数字:(【参考方案2】:firebase
.storage()
.ref(`images/$directory/$file.name`)
.put(file)
.on(
"state_changed",
(snapshot) =>
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
this.setState( progress );
,
(error) => this.setState( error: error.message )
);
【讨论】:
以上是关于React + Firebase 存储 + 文件上传和进度显示的主要内容,如果未能解决你的问题,请参考以下文章
使用 Firestore 通过“react-redux-firebase”存储配置文件数据?
为啥我没有在我的 react 应用程序中获取 firebase 存储文件 url?
React + Firebase 存储 + 文件上传和进度显示
使用 react native expo 将文件上传到 firebase 存储